summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2009-10-25 18:35:46 +0100
committerMichael Bien <[email protected]>2009-10-25 18:35:46 +0100
commit30cd68083930688693ebdfefdeda609d857a2c8a (patch)
tree96f7a2625bb393510ded578566f2378bc25c856a
parent054e5005d1429ba6ea4f9283eee2988ff54d1abb (diff)
implemented clCreateContext(...) and updated Tests and high level binding.
-rw-r--r--resources/clImplCustomCode.c60
-rw-r--r--resources/clImplCustomCode.java23
-rw-r--r--src/com/mbien/opencl/CLContext.java61
-rw-r--r--src/com/mbien/opencl/CLDevice.java22
-rw-r--r--test/com/mbien/opencl/LowLevelBindingTest.java53
5 files changed, 179 insertions, 40 deletions
diff --git a/resources/clImplCustomCode.c b/resources/clImplCustomCode.c
index a35328dc..57d1c3e3 100644
--- a/resources/clImplCustomCode.c
+++ b/resources/clImplCustomCode.c
@@ -52,40 +52,64 @@ Java_com_mbien_opencl_impl_CLImpl_clCreateContextFromType1(JNIEnv *env, jobject
return (jlong)_ctx;
}
-
/*
+ * Entry point to C language function:
+ *extern CL_API_ENTRY cl_context CL_API_CALL
+ *clCreateContext(cl_context_properties * properties ,
+ * cl_uint num_devices ,
+ * const cl_device_id * devices ,
+ * void (*pfn_notify)(const char *, const void *, size_t, void *) pfn_notify ,
+ * void * user_data ,
+ * cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0;
+ */
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) {
+Java_com_mbien_opencl_impl_CLImpl_clCreateContext1(JNIEnv *env, jobject _unused,
+ jobject props, jint props_byte_offset, jint numDevices, jobject deviceList, jobject cb, jobject data, jobject errcode, jint errcode_byte_offset) {
intptr_t * _props_ptr = NULL;
int32_t * _errcode_ptr = NULL;
- void * _device_ptr = NULL;
+ size_t * _deviceListPtr = NULL;
- cl_context _res;
+ cl_context _ctx;
if (props != NULL) {
- _props_ptr = (intptr_t *) (((char*) (*env)->GetDirectBufferAddress(env, props)) + props_byte_offset);
+ _props_ptr = (void *) (((char*) (*env)->GetPrimitiveArrayCritical(env, props, NULL)) + props_byte_offset);
+ }
+ if (deviceList != NULL) {
+ _deviceListPtr = (void *) (((char*) (*env)->GetPrimitiveArrayCritical(env, deviceList, NULL)) /*+ device_byte_offset*/);
+ }
+ if (errcode != NULL) {
+ _errcode_ptr = (void *) (((char*) (*env)->GetPrimitiveArrayCritical(env, errcode, NULL)) + errcode_byte_offset);
}
- if (device_type != NULL) {
- _device_ptr = (void *) (((char*) (*env)->GetPrimitiveArrayCritical(env, device_type, NULL)));
- }
+ // TODO payload, callback...
+ _ctx = clCreateContext((cl_context_properties *) _props_ptr, numDevices, (cl_device_id *)_deviceListPtr, NULL, NULL, (int32_t *) _errcode_ptr);
- _res = clCreateContext();
+ if (errcode != NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, errcode, _errcode_ptr, 0);
+ }
+ if (deviceList != NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, deviceList, _deviceListPtr, 0);
+ }
+ if (props != NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, props, _props_ptr, 0);
+ }
- if (device_type != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, device_type, _device_ptr, 0);
- }
- return (jlong) (intptr_t) _res;
+ return (jlong) _ctx;
}
-*/
/**
- * Entry point to C language function: <code> int32_t clBuildProgram(cl_program, uint32_t, cl_device_id * , const char * , void (*pfn_notify)(cl_program, void *user_data), void * );
+ * Entry point to C language function:
+ * extern CL_API_ENTRY cl_int CL_API_CALL
+ *clBuildProgram(cl_program program ,
+ * cl_uint num_devices ,
+ * const cl_device_id * device_list ,
+ * const char * options ,
+ * void (*pfn_notify)(cl_program program , void * user_data ),
+ * void * user_data ) CL_API_SUFFIX__VERSION_1_0;
*/
JNIEXPORT jint JNICALL
-Java_com_mbien_opencl_impl_CLImpl_clBuildProgram0(JNIEnv *env, jobject _unused,
+Java_com_mbien_opencl_impl_CLImpl_clBuildProgram1(JNIEnv *env, jobject _unused,
jlong program, jint deviceCount, jobject deviceList, jint offset, jstring options, jobject cb, jobject data) {
const char* _strchars_options = NULL;
@@ -106,7 +130,7 @@ Java_com_mbien_opencl_impl_CLImpl_clBuildProgram0(JNIEnv *env, jobject _unused,
}
// TODO payload, callback...
- _res = clBuildProgram((cl_program)program, (cl_uint)deviceCount, _deviceListPtr, _strchars_options, NULL, NULL);
+ _res = clBuildProgram((cl_program)program, (cl_uint)deviceCount, (cl_device_id *)_deviceListPtr, _strchars_options, NULL, NULL);
if (deviceList != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, deviceList, _deviceListPtr, 0);
diff --git a/resources/clImplCustomCode.java b/resources/clImplCustomCode.java
index 0d25ddb6..d74d5b82 100644
--- a/resources/clImplCustomCode.java
+++ b/resources/clImplCustomCode.java
@@ -1,10 +1,21 @@
- public long clCreateContext(IntBuffer properties, long[] devices, CreateContextCallback cb, Object userData, IntBuffer errcode_ret) {
+ public long clCreateContext(IntBuffer properties, long[] devices, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret) {
- throw new RuntimeException("not yet implemented, use clCreateContextFromType instead");
-// return this.clCreateContext0(properties, offset1, devices, cb, null, errcode_ret, offset2);
+ if(pfn_notify != null)
+ throw new RuntimeException("asynchronous execution with callback is not yet implemented, pass null through this method to block until complete.");
+
+ if(userData != null)
+ System.err.println("WARNING: userData not yet implemented... ignoring");
+
+ int listLength = 0;
+ if(devices != null)
+ listLength = devices.length;
+
+ return this.clCreateContext1(
+ BufferFactory.getArray(properties), BufferFactory.getIndirectBufferByteOffset(properties), listLength, devices, null, null,
+ BufferFactory.getArray(errcode_ret), BufferFactory.getIndirectBufferByteOffset(errcode_ret) );
}
- private native long clCreateContext0(Object cl_context_properties, int props_offset, long[] devices, CreateContextCallback pfn_notify, Object userData, Object errcode_ret, int err_offset);
+ private native long clCreateContext1(Object cl_context_properties, int props_offset, int deviceCount, long[] devices, CreateContextCallback pfn_notify, Object userData, Object errcode_ret, int err_offset);
public long clCreateContextFromType(IntBuffer properties, long device_type, CreateContextCallback pfn_notify, Object userData, IntBuffer errcode_ret) {
@@ -35,8 +46,8 @@
if(deviceList != null)
listLength = deviceList.length;
- return clBuildProgram0(program, listLength, deviceList, 0, options, cb, userData);
+ return clBuildProgram1(program, listLength, deviceList, 0, options, cb, userData);
}
/** Entry point to C language function: <code> int32_t clBuildProgram(cl_program, uint32_t, cl_device_id * , const char * , void * ); </code> */
- private native int clBuildProgram0(long program, int devices, Object deviceList, int arg2_byte_offset, String options, BuildProgramCallback cb, Object userData);
+ private native int clBuildProgram1(long program, int devices, Object deviceList, int arg2_byte_offset, String options, BuildProgramCallback cb, Object userData);
diff --git a/src/com/mbien/opencl/CLContext.java b/src/com/mbien/opencl/CLContext.java
index 81ac58f0..68ff131c 100644
--- a/src/com/mbien/opencl/CLContext.java
+++ b/src/com/mbien/opencl/CLContext.java
@@ -66,29 +66,44 @@ public final class CLContext {
}
/**
- * Creates a default context on all available devices (CL_DEVICE_TYPE_ALL).
+ * Creates a context on all available devices (CL_DEVICE_TYPE_ALL).
* The platform to be used is implementation dependent.
*/
public static final CLContext create() {
- return createContext(null, CL.CL_DEVICE_TYPE_ALL);
+ return createContextFromType(null, CL.CL_DEVICE_TYPE_ALL);
}
/**
- * Creates a default context on the specified device types.
+ * Creates a context on the specified device types.
* The platform to be used is implementation dependent.
*/
public static final CLContext create(CLDevice.Type... deviceTypes) {
return create(null, deviceTypes);
}
+ /**
+ * Creates a context on the specified devices.
+ * The platform to be used is implementation dependent.
+ */
+ public static final CLContext create(CLDevice... devices) {
+ return create(null, devices);
+ }
+
+ /**
+ * Creates a context on the specified platform on all available devices (CL_DEVICE_TYPE_ALL).
+ */
+ public static final CLContext create(CLPlatform platform) {
+ return create(platform, CLDevice.Type.ALL);
+ }
+
// TODO check if driver bug, otherwise find the reason why this is not working (INVALID_VALUE with NV driver)
/**
- * Creates a default context on the specified platform and with the specified
+ * Creates a context on the specified platform and with the specified
* device types.
*/
private static final CLContext create(CLPlatform platform, CLDevice.Type... deviceTypes) {
- int type = 0;
+ long type = 0;
if(deviceTypes != null) {
for (int i = 0; i < deviceTypes.length; i++) {
type |= deviceTypes[i].CL_TYPE;
@@ -102,10 +117,32 @@ public final class CLContext {
properties.rewind();
}
- return createContext(properties, type);
+ return createContextFromType(properties, type);
+ }
+
+ /**
+ * Creates a context on the specified platform and with the specified
+ * devices.
+ */
+ private static final CLContext create(CLPlatform platform, CLDevice... devices) {
+
+ long[] deviceIDs = new long[devices.length];
+
+ for (int i = 0; i < devices.length; i++) {
+ deviceIDs[i] = devices[i].ID;
+ }
+
+ IntBuffer properties = null;
+ if(platform != null) {
+ properties = IntBuffer.allocate(3);
+ properties.put(CL.CL_CONTEXT_PLATFORM).put((int)platform.ID).put(0); // TODO check if this has to be int or long
+ properties.rewind();
+ }
+
+ return createContext(properties, deviceIDs);
}
- private static final CLContext createContext(IntBuffer properties, long deviceType) {
+ private static final CLContext createContextFromType(IntBuffer properties, long deviceType) {
IntBuffer status = IntBuffer.allocate(1);
long context = CLPlatform.getLowLevelBinding().clCreateContextFromType(properties, deviceType, null, null, status);
@@ -115,6 +152,16 @@ public final class CLContext {
return new CLContext(context);
}
+ private static final CLContext createContext(IntBuffer properties, long[] devices) {
+
+ IntBuffer status = IntBuffer.allocate(1);
+ long context = CLPlatform.getLowLevelBinding().clCreateContext(properties, devices, null, null, status);
+
+ checkForError(status.get(), "can not create CL context");
+
+ return new CLContext(context);
+ }
+
/**
* Creates a program from the given sources, the program is not build yet.
*/
diff --git a/src/com/mbien/opencl/CLDevice.java b/src/com/mbien/opencl/CLDevice.java
index 0ad8f0e9..de49aafa 100644
--- a/src/com/mbien/opencl/CLDevice.java
+++ b/src/com/mbien/opencl/CLDevice.java
@@ -255,21 +255,31 @@ public final class CLDevice {
*/
ACCELERATOR(CL.CL_DEVICE_TYPE_ACCELERATOR),
/**
- * CL_DEVICE_TYPE_DEFAULT
+ * CL_DEVICE_TYPE_DEFAULT. This type can be used for creating a context on
+ * the default device, a single device can never have this type.
*/
- DEFAULT(CL.CL_DEVICE_TYPE_DEFAULT);
+ DEFAULT(CL.CL_DEVICE_TYPE_DEFAULT),
+ /**
+ * CL_DEVICE_TYPE_ALL. This type can be used for creating a context on
+ * all devices, a single device can never have this type.
+ */
+ ALL(CL.CL_DEVICE_TYPE_ALL);
/**
* Value of wrapped OpenCL device type.
*/
- public final int CL_TYPE;
+ public final long CL_TYPE;
- private Type(int CL_TYPE) {
+ private Type(long CL_TYPE) {
this.CL_TYPE = CL_TYPE;
}
- public static Type valueOf(int clDeviceType) {
- switch(clDeviceType) {
+ public static Type valueOf(long clDeviceType) {
+
+ if(clDeviceType == CL.CL_DEVICE_TYPE_ALL)
+ return ALL;
+
+ switch((int)clDeviceType) {
case(CL.CL_DEVICE_TYPE_DEFAULT):
return DEFAULT;
case(CL.CL_DEVICE_TYPE_CPU):
diff --git a/test/com/mbien/opencl/LowLevelBindingTest.java b/test/com/mbien/opencl/LowLevelBindingTest.java
index 3776a349..bff9db36 100644
--- a/test/com/mbien/opencl/LowLevelBindingTest.java
+++ b/test/com/mbien/opencl/LowLevelBindingTest.java
@@ -3,6 +3,7 @@ package com.mbien.opencl;
import com.sun.gluegen.runtime.CPU;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.IntBuffer;
import java.util.Arrays;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -47,7 +48,7 @@ public class LowLevelBindingTest {
}
@Test
- public void lowLevelTest1() {
+ public void contextlessTest() {
out.println(" - - - lowLevelTest; contextless binding - - - ");
@@ -118,7 +119,53 @@ public class LowLevelBindingTest {
}
@Test
- public void lowLevelTest2() {
+ public void createContextTest() {
+
+ out.println(" - - - createContextTest - - - ");
+
+ CL cl = CLPlatform.getLowLevelBinding();
+
+ int[] intArray = new int[1];
+ // find all available OpenCL platforms
+ int ret = cl.clGetPlatformIDs(0, null, 0, intArray, 0);
+ checkForError(ret);
+ out.println("#platforms: "+intArray[0]);
+
+ long[] longArray = new long[intArray[0]];
+ ret = cl.clGetPlatformIDs(longArray.length, longArray, 0, null, 0);
+ checkForError(ret);
+
+ long platform = longArray[0];
+
+ //find all devices
+ ret = cl.clGetDeviceIDs(platform, CL.CL_DEVICE_TYPE_ALL, 0, null, 0, intArray, 0);
+ checkForError(ret);
+ out.println("#devices: "+intArray[0]);
+
+ long[] devices = new long[intArray[0]];
+ ret = cl.clGetDeviceIDs(platform, CL.CL_DEVICE_TYPE_ALL, devices.length, devices, 0, null, 0);
+
+ IntBuffer intBuffer = IntBuffer.allocate(1);
+ long context = cl.clCreateContext(null, devices, null, null, intBuffer);
+ checkError("on clCreateContext", intBuffer.get());
+
+ //get number of devices
+ ret = cl.clGetContextInfo(context, CL.CL_CONTEXT_DEVICES, 0, null, longArray, 0);
+ checkError("on clGetContextInfo", ret);
+
+ int sizeofLong = (CPU.is32Bit()?4:8);
+ out.println("context created with " + longArray[0]/sizeofLong + " devices");
+
+ //check if equal
+ assertEquals("context was not created on all devices specified", devices.length, longArray[0]/sizeofLong);
+
+ ret = cl.clReleaseContext(context);
+ checkError("on clReleaseContext", ret);
+ }
+
+
+ @Test
+ public void lowLevelVectorAddTest() {
out.println(" - - - lowLevelTest2; VectorAdd kernel - - - ");
@@ -295,7 +342,7 @@ public class LowLevelBindingTest {
out.println(" - - - loadTest - - - ");
for(int i = 0; i < 100; i++) {
out.println("###iteration "+i);
- lowLevelTest2();
+ lowLevelVectorAddTest();
}
}