diff options
-rw-r--r-- | src/com/mbien/opencl/CLCommandQueue.java | 17 | ||||
-rw-r--r-- | src/com/mbien/opencl/CLDevice.java | 289 | ||||
-rw-r--r-- | src/com/mbien/opencl/CLException.java | 3 | ||||
-rw-r--r-- | test/com/mbien/opencl/HighLevelBindingTest.java | 22 |
4 files changed, 326 insertions, 5 deletions
diff --git a/src/com/mbien/opencl/CLCommandQueue.java b/src/com/mbien/opencl/CLCommandQueue.java index 28c4bad0..d58cc162 100644 --- a/src/com/mbien/opencl/CLCommandQueue.java +++ b/src/com/mbien/opencl/CLCommandQueue.java @@ -1,5 +1,8 @@ package com.mbien.opencl; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; import static com.mbien.opencl.CLException.*; /** @@ -226,5 +229,19 @@ public class CLCommandQueue { } return null; } + + public static EnumSet<Mode> valuesOf(int bitfield) { + List<Mode> matching = new ArrayList<Mode>(); + Mode[] values = Mode.values(); + for (Mode value : values) { + if((value.CL_QUEUE_MODE & bitfield) != 0) + matching.add(value); + } + if(matching.isEmpty()) + return EnumSet.noneOf(Mode.class); + else + return EnumSet.copyOf(matching); + } + } } diff --git a/src/com/mbien/opencl/CLDevice.java b/src/com/mbien/opencl/CLDevice.java index de49aafa..78f0f7bf 100644 --- a/src/com/mbien/opencl/CLDevice.java +++ b/src/com/mbien/opencl/CLDevice.java @@ -2,8 +2,11 @@ package com.mbien.opencl; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashSet; +import java.util.List; import java.util.Scanner; import java.util.Set; @@ -147,6 +150,126 @@ public final class CLDevice { } /** + * Returns the size of global memory cache line in bytes. + */ + public long getGlobalMemCachlineSize() { + return getInfoLong(CL.CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE); + } + + /** + * Returns the size of global memory cache in bytes. + */ + public long getGlobalMemCachSize() { + return getInfoLong(CL.CL_DEVICE_GLOBAL_MEM_CACHE_SIZE); + } + + /** + * Returns true if images are supported by the OpenCL device and false otherwise. + */ + public boolean isImageSupportAvailable() { + return getInfoLong(CL.CL_DEVICE_IMAGE_SUPPORT) == CL.CL_TRUE; + } + + /** + * Returns the max number of simultaneous image objects that can be read by a kernel. + * The minimum value is 128 if image support is available. + */ + public int getMaxReadImageArgs() { + return (int)getInfoLong(CL.CL_DEVICE_MAX_READ_IMAGE_ARGS); + } + + /** + * Returns the max number of simultaneous image objects that can be written by a kernel. + * The minimum value is 8 if image support is available. + */ + public int getMaxWriteImageArgs() { + return (int)getInfoLong(CL.CL_DEVICE_MAX_WRITE_IMAGE_ARGS); + } + + /** + * Returns the max width of 2D image in pixels. The minimum value is 8192 if + * image support is available. + */ + public int getMaxImage2dWidth() { + return (int)getInfoLong(CL.CL_DEVICE_IMAGE2D_MAX_WIDTH); + } + + /** + * Returns the max height of 2D image in pixels. The minimum value is 8192 if + * image support is available. + */ + public int getMaxImage2dHeight() { + return (int)getInfoLong(CL.CL_DEVICE_IMAGE2D_MAX_HEIGHT); + } + + /** + * Returns the max width of 3D image in pixels. The minimum value is 2048 if + * image support is available. + */ + public int getMaxImage3dWidth() { + return (int)getInfoLong(CL.CL_DEVICE_IMAGE3D_MAX_WIDTH); + } + + /** + * Returns the max height of 3D image in pixels. The minimum value is 2048 if + * image support is available. + */ + public int getMaxImage3dHeight() { + return (int)getInfoLong(CL.CL_DEVICE_IMAGE3D_MAX_HEIGHT); + } + + /** + * Returns the max depth of 3D image in pixels. The minimum value is 2048 if + * image support is available. + */ + public int getMaxImage3dDepth() { + return (int)getInfoLong(CL.CL_DEVICE_IMAGE3D_MAX_DEPTH); + } + + /** + * Returns the maximum number of samplers that can be used in a kernel. The + * minimum value is 16 if image support is available. + */ + public int getMaxSamplers() { + return (int)getInfoLong(CL.CL_DEVICE_MAX_SAMPLERS); + } + + /** + * Returns the resolution of device timer. This is measured in nanoseconds. + */ + public long getProfilingTimerResolution() { + return getInfoLong(CL.CL_DEVICE_PROFILING_TIMER_RESOLUTION); + } + + /** + * Returns the single precision floating-point capability of the device. + */ + public EnumSet<SingleFPConfig> getSingleFPConfig() { + return SingleFPConfig.valuesOf((int)getInfoLong(CL.CL_DEVICE_SINGLE_FP_CONFIG)); + } + + /** + * Returns the local memory type. + */ + public LocalMemType getLocalMemType() { + return LocalMemType.valueOf((int)getInfoLong(CL.CL_DEVICE_LOCAL_MEM_TYPE)); + } + + /** + * Returns the type of global memory cache supported. + */ + public GlobalMemCacheType getGlobalMemCacheType() { + return GlobalMemCacheType.valueOf((int)getInfoLong(CL.CL_DEVICE_GLOBAL_MEM_CACHE_TYPE)); + } + + /** + * Returns the command-queue properties properties supported by the device. + */ + public EnumSet<CLCommandQueue.Mode> getQueueProperties() { + return CLCommandQueue.Mode.valuesOf((int)getInfoLong(CL.CL_DEVICE_QUEUE_PROPERTIES)); + } + + /** * Returns true if this device is available. */ public boolean isAvailable() { @@ -163,6 +286,22 @@ public final class CLDevice { } /** + * Returns true if the OpenCL device is a little endian device and false otherwise. + */ + public boolean isLittleEndianAvailable() { + return getInfoLong(CL.CL_DEVICE_ENDIAN_LITTLE) == CL.CL_TRUE; + } + + /** + * Returns true if the device implements error correction for the memories, + * caches, registers etc. in the device. Is false if the device does not + * implement error correction. + */ + public boolean isErrorCorrectionSupported() { + return getInfoLong(CL.CL_DEVICE_ERROR_CORRECTION_SUPPORT) == CL.CL_TRUE; + } + + /** * Returns all device extension names as unmodifiable Set. */ public Set<String> getExtensions() { @@ -178,10 +317,6 @@ public final class CLDevice { return Collections.unmodifiableSet(extSet); } - //TODO CL_DEVICE_IMAGE_SUPPORT - //TODO CL_DEVICE_MAX_WORK_ITEM_SIZES - - private final long getInfoLong(int key) { ByteBuffer bb = ByteBuffer.allocate(8); @@ -197,7 +332,7 @@ public final class CLDevice { public final String getInfoString(int key) { long[] longBuffer = new long[1]; - ByteBuffer bb = ByteBuffer.allocate(512); + ByteBuffer bb = ByteBuffer.allocate(512); // TODO use a cache int ret = cl.clGetDeviceInfo(ID, key, bb.capacity(), bb, longBuffer, 0); @@ -293,4 +428,148 @@ public final class CLDevice { } } + /** + * Describes single precision floating-point capability of the device. + * One or more values are possible. + */ + public enum SingleFPConfig { + + /** + * denorms are supported. + */ + DENORM(CL.CL_FP_DENORM), + + /** + * INF and quiet NaNs are supported. + */ + INF_NAN(CL.CL_FP_INF_NAN), + + /** + * round to nearest rounding mode supported. + */ + ROUND_TO_NEAREST(CL.CL_FP_ROUND_TO_NEAREST), + + /** + * round to +ve and –ve infinity rounding modes supported. + */ + ROUND_TO_INF(CL.CL_FP_ROUND_TO_INF), + + /** + * round to zero rounding mode supported. + */ + ROUND_TO_ZERO(CL.CL_FP_ROUND_TO_ZERO), + + /** + * IEEE754-2008 fused multiply-add is supported. + */ + FMA(CL.CL_FP_FMA); + + + /** + * Value of wrapped OpenCL bitfield. + */ + public final int CL_VALUE; + + private SingleFPConfig(int CL_VALUE) { + this.CL_VALUE = CL_VALUE; + } + + /** + * Returns a EnumSet for the given bitfield. + */ + public static EnumSet<SingleFPConfig> valuesOf(int bitfield) { + List<SingleFPConfig> matching = new ArrayList<SingleFPConfig>(); + SingleFPConfig[] values = SingleFPConfig.values(); + for (SingleFPConfig value : values) { + if((value.CL_VALUE & bitfield) != 0) + matching.add(value); + } + if(matching.isEmpty()) + return EnumSet.noneOf(SingleFPConfig.class); + else + return EnumSet.copyOf(matching); + } + + } + + /** + * Type of global memory cache supported. + */ + public enum GlobalMemCacheType { + + /** + * Global memory cache not supported. + */ + NONE(CL.CL_NONE), + + /** + * Read only cache. + */ + READ_ONLY(CL.CL_READ_ONLY_CACHE), + + /** + * Read-write cache. + */ + READ_WRITE(CL.CL_READ_WRITE_CACHE); + + + /** + * Value of wrapped OpenCL value. + */ + public final int CL_VALUE; + + private GlobalMemCacheType(int CL_VALUE) { + this.CL_VALUE = CL_VALUE; + } + + /** + * Returns the matching GlobalMemCacheType for the given cl type. + */ + public static GlobalMemCacheType valueOf(int bitfield) { + GlobalMemCacheType[] values = GlobalMemCacheType.values(); + for (GlobalMemCacheType value : values) { + if(value.CL_VALUE == bitfield) + return value; + } + return null; + } + } + + /** + * Type of local memory cache supported. + */ + public enum LocalMemType { + + /** + * GLOBAL implies that no dedicated memory storage is available (global mem is used instead). + */ + GLOBAL(CL.CL_GLOBAL), + + /** + * LOCAL implies dedicated local memory storage such as SRAM. + */ + LOCAL(CL.CL_LOCAL); + + /** + * Value of wrapped OpenCL value. + */ + public final int CL_VALUE; + + private LocalMemType(int CL_VALUE) { + this.CL_VALUE = CL_VALUE; + } + + /** + * Returns the matching LocalMemCacheType for the given cl type. + */ + public static LocalMemType valueOf(int clLocalCacheType) { + if(clLocalCacheType == CL.CL_GLOBAL) + return LOCAL; + else if(clLocalCacheType == CL.CL_LOCAL) + return GLOBAL; + return null; + } + + } + } diff --git a/src/com/mbien/opencl/CLException.java b/src/com/mbien/opencl/CLException.java index 5806d41d..b4a66a9f 100644 --- a/src/com/mbien/opencl/CLException.java +++ b/src/com/mbien/opencl/CLException.java @@ -166,6 +166,9 @@ public class CLException extends RuntimeException { case CL.CL_INVALID_MIP_LEVEL: return "CL_INVALID_MIP_LEVEL"; + case CL.CL_INVALID_GLOBAL_WORK_SIZE: + return "CL_INVALID_GLOBAL_WORK_SIZE"; + default: return "unknown cause: error " + error; } diff --git a/test/com/mbien/opencl/HighLevelBindingTest.java b/test/com/mbien/opencl/HighLevelBindingTest.java index 85dbda1d..915a5ce2 100644 --- a/test/com/mbien/opencl/HighLevelBindingTest.java +++ b/test/com/mbien/opencl/HighLevelBindingTest.java @@ -1,8 +1,11 @@ package com.mbien.opencl; import com.mbien.opencl.CLBuffer.Mem; +import com.mbien.opencl.CLCommandQueue.Mode; +import com.mbien.opencl.CLDevice.SingleFPConfig; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.EnumSet; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; @@ -29,6 +32,18 @@ public class HighLevelBindingTest { out.println(" - - - highLevelTest; contextless - - - "); + // enum tests + final EnumSet<SingleFPConfig> singleFPConfig = SingleFPConfig.valuesOf(CL.CL_FP_DENORM | CL.CL_FP_ROUND_TO_INF); + assertEquals(0, SingleFPConfig.valuesOf(0).size()); + assertTrue(singleFPConfig.contains(SingleFPConfig.DENORM)); + assertTrue(singleFPConfig.contains(SingleFPConfig.ROUND_TO_INF)); + + final EnumSet<Mode> queueMode = Mode.valuesOf(CL.CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL.CL_QUEUE_PROFILING_ENABLE); + assertEquals(0, Mode.valuesOf(0).size()); + assertTrue(queueMode.contains(Mode.OUT_OF_ORDER_EXEC_MODE)); + assertTrue(queueMode.contains(Mode.PROFILING_MODE)); + + // platform/device info tests CLPlatform[] clPlatforms = CLPlatform.listCLPlatforms(); for (CLPlatform platform : clPlatforms) { @@ -49,7 +64,14 @@ public class HighLevelBindingTest { out.println(" type: "+device.getType()); out.println(" global mem: "+device.getGlobalMemSize()/(1024*1024)+" MB"); out.println(" local mem: "+device.getLocalMemSize()/1024+" KB"); + out.println(" local mem type: "+device.getLocalMemType()); + out.println(" global mem cache size: "+device.getGlobalMemCachSize()); + out.println(" global mem cache type: "+device.getGlobalMemCacheType()); + out.println(" constant buffer size: "+device.getMaxConstantBufferSize()); + out.println(" queue properties: "+device.getQueueProperties()); out.println(" clock: "+device.getMaxClockFrequency()+" MHz"); + out.println(" timer res: "+device.getProfilingTimerResolution()+" ns"); + out.println(" single FP config: "+device.getSingleFPConfig()); out.println(" max work group size: "+device.getMaxWorkGroupSize()); out.println(" max compute units: "+device.getMaxComputeUnits()); out.println(" extensions: "+device.getExtensions()); |