aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resources/cl-if.cfg4
-rw-r--r--resources/clImplCustomCode.c28
-rw-r--r--resources/clImplCustomCode.java8
-rw-r--r--src/com/mbien/opencl/CLContext.java84
-rw-r--r--src/com/mbien/opencl/CLDevice.java179
-rw-r--r--src/com/mbien/opencl/CLPlatform.java11
-rw-r--r--test/com/mbien/opencl/JOCLTest.java52
7 files changed, 330 insertions, 36 deletions
diff --git a/resources/cl-if.cfg b/resources/cl-if.cfg
index 6d23789d..08e21dcc 100644
--- a/resources/cl-if.cfg
+++ b/resources/cl-if.cfg
@@ -17,11 +17,11 @@ Ignore CL_GL_.*|cl.*GL.*
#custom implementations
Ignore clCreateContext
CustomJavaCode CL /** Interface to C language function: <br> <code> cl_context clCreateContext(intptr_t * , uint32_t, cl_device_id * , void (*pfn_notify)(const char *, const void *, size_t, void *), void *, int32_t * ); </code> */
-CustomJavaCode CL public long clCreateContext(IntBuffer properties, int arg1, long[] devices, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret);
+CustomJavaCode CL public long clCreateContext(IntBuffer properties, int properties_offset, long[] devices, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret, int errcode_offset);
Ignore clCreateContextFromType
CustomJavaCode CL /** Interface to C language function: <br> <code> cl_context clCreateContextFromType(cl_context_properties *properties, cl_device_type device_type, void (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data), void *user_data, cl_int *errcode_ret) ; </code> */
-CustomJavaCode CL public long clCreateContextFromType(IntBuffer properties, long device_type, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret);
+CustomJavaCode CL public long clCreateContextFromType(IntBuffer properties, int properties_offset, long device_type, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret, int errcode_offset);
Ignore clBuildProgram
#TODO..
diff --git a/resources/clImplCustomCode.c b/resources/clImplCustomCode.c
index a9847833..83d25938 100644
--- a/resources/clImplCustomCode.c
+++ b/resources/clImplCustomCode.c
@@ -23,6 +23,12 @@ Java_com_mbien_opencl_impl_CLImpl_clCreateContextFromType0(JNIEnv *env, jobject
intptr_t * _props_ptr = NULL;
int32_t * _errcode_ptr = NULL;
+/*
+ printf("jlong: %zu \n", sizeof(jlong) );
+ printf("intptr_t: %zu \n", sizeof(intptr_t));
+ printf("size_t: %zu \n", sizeof(size_t));
+*/
+
cl_context _res;
if (props != NULL) {
@@ -38,14 +44,34 @@ Java_com_mbien_opencl_impl_CLImpl_clCreateContextFromType0(JNIEnv *env, jobject
return (jlong) (intptr_t) _res;
}
-//clCreateContext0(IntBuffer properties, int size, long[] devices, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret, int size2)
+
/*
JNIEXPORT jlong JNICALL
Java_com_mbien_opencl_impl_CLImpl_clCreateContext0(JNIEnv *env, jobject _unused,
jobject props, jint props_byte_offset, jlong device_type, jobject cb, jobject data, jobject errcode, jint errcode_byte_offset) {
+ intptr_t * _props_ptr = NULL;
+ int32_t * _errcode_ptr = NULL;
+ void * _device_ptr = NULL;
+ cl_context _res;
+ if (props != NULL) {
+ _props_ptr = (intptr_t *) (((char*) (*env)->GetDirectBufferAddress(env, props)) + props_byte_offset);
+ }
+
+ if (device_type != NULL) {
+ _device_ptr = (void *) (((char*) (*env)->GetPrimitiveArrayCritical(env, device_type, NULL)));
+ }
+
+ _res = clCreateContext();
+
+ if (device_type != NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, device_type, _device_ptr, 0);
+ }
+ return (jlong) (intptr_t) _res;
}
*/
+
+
diff --git a/resources/clImplCustomCode.java b/resources/clImplCustomCode.java
index 2fa48d64..5ccc3b02 100644
--- a/resources/clImplCustomCode.java
+++ b/resources/clImplCustomCode.java
@@ -1,13 +1,13 @@
- public long clCreateContext(IntBuffer properties, int arg1, long[] devices, CreateContextCallback cb, Object userData, IntBuffer errcode_ret) {
- return this.clCreateContext0(properties, arg1, devices, cb, null, errcode_ret, 0);
+ public long clCreateContext(IntBuffer properties, int offset1, long[] devices, CreateContextCallback cb, Object userData, IntBuffer errcode_ret, int offset2) {
+ return this.clCreateContext0(properties, offset1, devices, cb, null, errcode_ret, offset2);
}
private native long clCreateContext0(IntBuffer properties, int size, long[] devices, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret, int size2);
- public long clCreateContextFromType(IntBuffer arg0, long device_type, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret) {
- return this.clCreateContextFromType0(arg0, 0, device_type, pfn_notify, null, errcode_ret, 0);
+ public long clCreateContextFromType(IntBuffer arg0, int offset1, long device_type, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret, int offset2) {
+ return this.clCreateContextFromType0(arg0, offset1, device_type, pfn_notify, null, errcode_ret, offset2);
}
private native long clCreateContextFromType0(IntBuffer arg0, int size, long device_type, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret, int size2);
diff --git a/src/com/mbien/opencl/CLContext.java b/src/com/mbien/opencl/CLContext.java
index dc3c7279..533d45d4 100644
--- a/src/com/mbien/opencl/CLContext.java
+++ b/src/com/mbien/opencl/CLContext.java
@@ -1,14 +1,18 @@
package com.mbien.opencl;
import com.mbien.opencl.impl.CLImpl;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
/**
*
* @author Michael Bien
*/
-public class CLContext {
+public final class CLContext {
private final static CL cl;
+ public final long contextID;
static{
System.loadLibrary("gluegen-rt");
@@ -16,6 +20,84 @@ public class CLContext {
cl = new CLImpl();
}
+ private CLContext(long contextID) {
+ this.contextID = contextID;
+ }
+
+ /**
+ * Creates a default context on all available devices.
+ */
+ public static CLContext create() {
+ IntBuffer ib = IntBuffer.allocate(1);
+ long context = cl.clCreateContextFromType(null, 0, CL.CL_DEVICE_TYPE_ALL, null, null, null, 0);
+
+// int errorCode = ib.get();
+// if(errorCode != CL.CL_SUCCESS)
+// throw new CLException(errorCode, "can not create CL context");
+
+ return new CLContext(context);
+ }
+
+ /**
+ * Creates a default context on the specified device types.
+ */
+ public static CLContext create(CLDevice.Type... deviceTypes) {
+
+ int type = deviceTypes[0].CL_TYPE;
+ for (int i = 1; i < deviceTypes.length; i++) {
+ type |= deviceTypes[i].CL_TYPE;
+ }
+
+ long context = cl.clCreateContextFromType(null, 0, type, null, null, null, 0);
+ return new CLContext(context);
+ }
+
+ /**
+ * Releases the context and all resources.
+ */
+ public void release() {
+ int ret = cl.clReleaseContext(contextID);
+ if(CL.CL_SUCCESS != ret)
+ throw new CLException(ret, "error releasing context");
+ }
+
+ /**
+ * Gets the device with maximal FLOPS from this context.
+ */
+ public CLDevice getMaxFlopsDevice() {
+
+ //TODO not finished
+
+ long[] longBuffer = new long[1];
+// ByteBuffer bb = ByteBuffer.allocate(8);
+// bb.order(ByteOrder.nativeOrder());
+
+ int ret = cl.clGetContextInfo(contextID, CL.CL_CONTEXT_DEVICES, 0, null, longBuffer, 0);
+ if(CL.CL_SUCCESS != ret)
+ throw new CLException(ret, "can not receive context info");
+
+ System.out.println("#devices: "+longBuffer[0]);
+
+ long[] deviceIDs = new long[(int)longBuffer[0]];
+ ret = cl.clGetContextInfo(contextID, CL.CL_CONTEXT_DEVICES, 0, null, deviceIDs, 0);
+
+ if(CL.CL_SUCCESS != ret)
+ throw new CLException(ret, "can not receive context info");
+
+ for (int i = 0; i < deviceIDs.length; i++) {
+ long l = deviceIDs[i];
+ System.out.println("device id"+l);
+ }
+
+ // get the list of GPU devices associated with context
+// ciErrNum = clGetContextInfo(cxGPUContext, CL_CONTEXT_DEVICES, 0, NULL, &dataBytes);
+// cl_device_id *cdDevices = (cl_device_id *)malloc(dataBytes);
+// ciErrNum |= clGetContextInfo(cxGPUContext, CL_CONTEXT_DEVICES, dataBytes, cdDevices, NULL);
+// shrCheckError(ciErrNum, CL_SUCCESS);
+
+ return null;
+ }
+
/**
* Lists all available OpenCL implementaitons.
* @throws CLException if something went wrong initializing OpenCL
diff --git a/src/com/mbien/opencl/CLDevice.java b/src/com/mbien/opencl/CLDevice.java
index 58d35fa9..3db2511f 100644
--- a/src/com/mbien/opencl/CLDevice.java
+++ b/src/com/mbien/opencl/CLDevice.java
@@ -1,15 +1,71 @@
package com.mbien.opencl;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Scanner;
+import java.util.Set;
/**
- *
+ *
* @author Michael Bien
*/
-public class CLDevice {
+public final class CLDevice {
+
+ //FIXME gluegen does not generate CL_DEVICE_TYPE_* remove hardcoded values ASAP
+
+ /**
+ * Enumeration for the type of a device.
+ */
+ public enum Type {
+ /**
+ * CL_DEVICE_TYPE_CPU
+ */
+ CPU(1 << 1),
+ /**
+ * CL_DEVICE_TYPE_GPU
+ */
+ GPU(1 << 2),
+ /**
+ * CL_DEVICE_TYPE_ACCELERATOR
+ */
+ ACCELERATOR(1 << 3),
+ /**
+ * CL_DEVICE_TYPE_DEFAULT
+ */
+ DEFAULT(1 << 0);
+
+ /**
+ * Value of wrapped OpenCL device type.
+ */
+ public final int CL_TYPE;
+
+ private Type(int CL_TYPE) {
+ this.CL_TYPE = CL_TYPE;
+ }
+
+ public static Type valueOf(int clDeviceType) {
+ switch(clDeviceType) {
+ case(1 << 0):
+ return DEFAULT;
+ case(1 << 1):
+ return CPU;
+ case(1 << 2):
+ return GPU;
+ case(1 << 3):
+ return ACCELERATOR;
+ }
+ return null;
+ }
+ }
private final CL cl;
- private final long deviceID;
+
+ /**
+ * OpenCL device id for this device.
+ */
+ public final long deviceID;
CLDevice(CL cl, long id) {
this.cl = cl;
@@ -23,7 +79,96 @@ public class CLDevice {
return getInfoString(CL.CL_DEVICE_NAME);
}
- public String getInfoString(int key) {
+ /**
+ * Returns the OpenCL profile of this device.
+ */
+ public String getProfile() {
+ return getInfoString(CL.CL_DEVICE_PROFILE);
+ }
+
+ /**
+ * Returns the vendor of this device.
+ */
+ public String getVendor() {
+ return getInfoString(CL.CL_DEVICE_VENDOR);
+ }
+
+ /**
+ * Returns the type of this device.
+ */
+ public Type getType() {
+ return Type.valueOf((int)getInfoLong(CL.CL_DEVICE_TYPE));
+ }
+
+ /**
+ * Returns the maximal number of compute units.
+ */
+ public int getMaxComputeUnits() {
+ return (int) getInfoLong(CL.CL_DEVICE_MAX_COMPUTE_UNITS);
+ }
+
+ /**
+ * Returns the maximal work group size.
+ */
+ public int getMaxWorkGroupSize() {
+ return (int) getInfoLong(CL.CL_DEVICE_MAX_WORK_GROUP_SIZE);
+ }
+
+ /**
+ * Returns the max clock frequency in Hz.
+ */
+ public int getMaxClockFrequency() {
+ return (int) (getInfoLong(CL.CL_DEVICE_MAX_CLOCK_FREQUENCY));
+ }
+
+ /**
+ * Returns the global memory size in Bytes.
+ */
+ public long getGlobalMemSize() {
+ return getInfoLong(CL.CL_DEVICE_GLOBAL_MEM_SIZE);
+ }
+
+ /**
+ * Returns the local memory size in Bytes.
+ */
+ public long getLocalMemSize() {
+ return getInfoLong(CL.CL_DEVICE_LOCAL_MEM_SIZE);
+ }
+
+ /**
+ * Returns all device extension names as unmodifiable Set.
+ */
+ public Set<String> getExtensions() {
+
+ String ext = getInfoString(CL.CL_DEVICE_EXTENSIONS);
+
+ Scanner scanner = new Scanner(ext);
+ Set<String> extSet = new HashSet<String>();
+
+ while(scanner.hasNext())
+ extSet.add(scanner.next());
+
+ 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);
+ bb.order(ByteOrder.nativeOrder());
+
+ int ret = cl.clGetDeviceInfo(deviceID, key, bb.capacity(), bb, null, 0);
+
+ if(CL.CL_SUCCESS != ret)
+ throw new CLException(ret, "can not receive device info");
+
+ return bb.getLong();
+ }
+
+ public final String getInfoString(int key) {
long[] longBuffer = new long[1];
ByteBuffer bb = ByteBuffer.allocate(512);
@@ -31,12 +176,32 @@ public class CLDevice {
int ret = cl.clGetDeviceInfo(deviceID, key, bb.capacity(), bb, longBuffer, 0);
if(CL.CL_SUCCESS != ret)
- throw new CLException(ret, "can not receive info string");
+ throw new CLException(ret, "can not receive device info string");
return new String(bb.array(), 0, (int)longBuffer[0]);
}
-// ret = cl.clGetDeviceInfo(device, CL.CL_DEVICE_TYPE, bb.capacity(), bb, longBuffer, 0);
-// assertEquals(CL.CL_SUCCESS, ret);
+
+ @Override
+ public String toString() {
+ return "CLPlatform [name:" + getName()
+ + " type:" + getType()
+ + " profile: " + getProfile()+"]";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj != null && obj instanceof CLDevice)
+ return ((CLDevice)obj).deviceID == deviceID;
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 79 * hash + (int) (this.deviceID ^ (this.deviceID >>> 32));
+ return hash;
+ }
+
}
diff --git a/src/com/mbien/opencl/CLPlatform.java b/src/com/mbien/opencl/CLPlatform.java
index 582e8abc..252872dc 100644
--- a/src/com/mbien/opencl/CLPlatform.java
+++ b/src/com/mbien/opencl/CLPlatform.java
@@ -6,9 +6,13 @@ import java.nio.ByteBuffer;
*
* @author Michael Bien
*/
-public class CLPlatform {
+public final class CLPlatform {
+
+ /**
+ * OpenCL platform id for this platform.
+ */
+ public final long platformID;
- private final long platformID;
private final CL cl;
CLPlatform(CL cl, long id) {
@@ -16,6 +20,9 @@ public class CLPlatform {
this.cl = cl;
}
+ /**
+ * Lists all physical devices available on this platform.
+ */
public CLDevice[] listCLDevices() {
int[] intBuffer = new int[1];
diff --git a/test/com/mbien/opencl/JOCLTest.java b/test/com/mbien/opencl/JOCLTest.java
index 3fdd4536..89292320 100644
--- a/test/com/mbien/opencl/JOCLTest.java
+++ b/test/com/mbien/opencl/JOCLTest.java
@@ -1,9 +1,8 @@
package com.mbien.opencl;
import com.mbien.opencl.impl.CLImpl;
-import java.nio.Buffer;
import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
+import java.nio.ByteOrder;
import java.util.Arrays;
import org.junit.After;
import org.junit.Before;
@@ -27,27 +26,41 @@ public class JOCLTest {
public void tearDownClass() throws Exception {
}
- @Test
+// @Test
public void highLevelTest() {
System.out.println(" - - - highLevelTest - - - ");
CLPlatform[] clPlatforms = CLContext.listCLPlatforms();
for (CLPlatform platform : clPlatforms) {
-
+
System.out.println("platform info:");
- System.out.println(platform.getName());
- System.out.println(platform.getProfile());
- System.out.println(platform.getVersion());
- System.out.println(platform.getVendor());
+ System.out.println("name: "+platform.getName());
+ System.out.println("profile: "+platform.getProfile());
+ System.out.println("version: "+platform.getVersion());
+ System.out.println("vendor: "+platform.getVendor());
CLDevice[] clDevices = platform.listCLDevices();
for (CLDevice device : clDevices) {
System.out.println("device info:");
- System.out.println(device.getName());
+ System.out.println("name: "+device.getName());
+ System.out.println("profile: "+device.getProfile());
+ System.out.println("vendor: "+device.getVendor());
+ System.out.println("type: "+device.getType());
+ System.out.println("global mem: "+device.getGlobalMemSize()/(1024*1024)+" MB");
+ System.out.println("local mem: "+device.getLocalMemSize()/1024+" KB");
+ System.out.println("clock: "+device.getMaxClockFrequency()+" MHz");
+ System.out.println("max work group size: "+device.getMaxWorkGroupSize());
+ System.out.println("max compute units: "+device.getMaxComputeUnits());
+ System.out.println("extensions: "+device.getExtensions());
}
}
+
+ CLContext ctx = CLContext.create();
+ CLDevice device = ctx.getMaxFlopsDevice();
+ System.out.println("max FLOPS device: " + device);
+ ctx.release();
}
@Test
@@ -55,10 +68,10 @@ public class JOCLTest {
System.out.println(" - - - lowLevelTest - - - ");
// already loaded
-// System.out.print("loading native libs...");
-// System.loadLibrary("gluegen-rt");
-// System.loadLibrary("jocl");
-// System.out.println("done");
+ System.out.print("loading native libs...");
+ System.loadLibrary("gluegen-rt");
+ System.loadLibrary("jocl");
+ System.out.println("done");
CreateContextCallback cb = new CreateContextCallback() {
@Override
@@ -86,6 +99,7 @@ public class JOCLTest {
// print platform info
long[] longBuffer = new long[1];
ByteBuffer bb = ByteBuffer.allocate(128);
+ bb.order(ByteOrder.nativeOrder());
for (int i = 0; i < platformId.length; i++) {
@@ -123,9 +137,10 @@ public class JOCLTest {
assertEquals(CL.CL_SUCCESS, ret);
System.out.println(" device: "+new String(bb.array(), 0, (int)longBuffer[0]));
-// ret = cl.clGetDeviceInfo(device, CL.CL_DEVICE_TYPE, bb.capacity(), bb, longBuffer, 0);
-// assertEquals(CL.CL_SUCCESS, ret);
-
+ ret = cl.clGetDeviceInfo(device, CL.CL_DEVICE_TYPE, bb.capacity(), bb, longBuffer, 0);
+ assertEquals(CL.CL_SUCCESS, ret);
+ System.out.println(" type: " + CLDevice.Type.valueOf(bb.get()));
+ bb.rewind();
}
@@ -133,16 +148,15 @@ public class JOCLTest {
Arrays.fill(longBuffer, 0);
- long context = cl.clCreateContextFromType(null, CL.CL_DEVICE_TYPE_ALL, cb, null, null);
+ long context = cl.clCreateContextFromType(null, 0, CL.CL_DEVICE_TYPE_ALL, cb, null, null, 0);
System.out.println("context handle: "+context);
ret = cl.clGetContextInfo(context, CL.CL_CONTEXT_DEVICES, 0, null, longBuffer, 0);
assertEquals(CL.CL_SUCCESS, ret);
System.out.println("CL_CONTEXT_DEVICES result: "+longBuffer[0]);
-// System.out.println("CL_CONTEXT_DEVICES result: "+buffer[1]);
-
+ cl.clReleaseContext(context);
}