summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/mbien/opencl/CLCommandQueue.java17
-rw-r--r--src/com/mbien/opencl/CLDevice.java289
-rw-r--r--src/com/mbien/opencl/CLException.java3
-rw-r--r--test/com/mbien/opencl/HighLevelBindingTest.java22
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());