diff --git a/CHANGELOG.md b/CHANGELOG.md
index c18842345c0fcba6b8d4e830188900847d1ebba2..b49633b1f7c930d3c1413018f577572a9dd20fd1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Aparapi jni Change Log
+## 1.3.2
+
+* Fixed local arrays handling 1D and ND, to cope with arrays resizing across kernel executions
+
## 1.3.1
* Fixed JVM crash with multi-dimensional arrays in Local memory (2D and 3D local arrays are now supported)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 30c0be3ef09fa7d4df7296f8ec32b765eaead2d0..c3c9e4cd4ad59f1c273ed1a20d690f543d45a4d4 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -27,4 +27,5 @@ Below are some of the specific details of various contributions.
* Steven Libby and Ryan Lamothe for #10 (Support for OpenMP, major refactoring cleanup and support for multidim arrays) March 28th 2013
* Paul Miner issue #61 and #115 (JTP Speed up and fixes to explicit puts) June 13th 2013
& lgalluci for his fix for issue #121 (incorrect toString for 3D ranges) July 6th 2013
-* Luis Mendes Issue #51 JVM crash when using multi-dimensional local arrays (refs #51)
\ No newline at end of file
+* Luis Mendes Issue #51 JVM crash when using multi-dimensional local arrays (refs #51)
+* Luis Mendes submitted local arrays handling 1D and ND, to cope with arrays resizing across kernel executions
\ No newline at end of file
diff --git a/configure.ac b/configure.ac
index 46e7deb5e5dd3887bd6409c59b9c835fc7cc4bb2..366d523e2e6253784bd3e36a07e6339b8968fe68 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libaparapi], [1.2.1], [syncleus@syncleus.com])
+AC_INIT([libaparapi], [1.3.2], [syncleus@syncleus.com])
AC_ENABLE_SHARED(yes)
AC_ENABLE_STATIC(no)
LT_INIT
diff --git a/src/cpp/runKernel/Aparapi.cpp b/src/cpp/runKernel/Aparapi.cpp
index 85ae3a2edad5af5d39c56a2c2af1afacba3fcc68..1e8938bc12d0f008f49871db302e30584df9f0b1 100644
--- a/src/cpp/runKernel/Aparapi.cpp
+++ b/src/cpp/runKernel/Aparapi.cpp
@@ -258,7 +258,7 @@ jint updateNonPrimitiveReferences(JNIEnv *jenv, jobject jobj, JNIContext* jniCon
//this won't be a problem with the aparapi buffers because
//we need to copy them every time anyway
- if (!arg->isPrimitive() && !arg->isAparapiBuffer()) {
+ if (!arg->isPrimitive() && !arg->isLocal() && !arg->isAparapiBuffer()) {
// Following used for all primitive arrays, object arrays and nio Buffers
jarray newRef = (jarray)jenv->GetObjectField(arg->javaArg, KernelArg::javaArrayFieldID);
if (config->isVerbose()){
@@ -304,10 +304,10 @@ jint updateNonPrimitiveReferences(JNIEnv *jenv, jobject jobj, JNIContext* jniCon
}
// Save the lengthInBytes which was set on the java side
- arg->syncSizeInBytes(jenv);
+ int lengthInBytes = arg->getSizeInBytes(jenv);
if (config->isVerbose()){
- fprintf(stderr, "updateNonPrimitiveReferences, args[%d].lengthInBytes=%d\n", i, arg->arrayBuffer->lengthInBytes);
+ fprintf(stderr, "updateNonPrimitiveReferences, args[%d].lengthInBytes=%d\n", i, lengthInBytes);
}
} // object has changed
}
@@ -356,6 +356,7 @@ void updateArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argP
else if (arg->isMutableByKernel()) mask |= CL_MEM_WRITE_ONLY;
arg->arrayBuffer->memMask = mask;
+ arg->arrayBuffer->syncMinimalParams(jenv, arg);
if (config->isVerbose()) {
strcpy(arg->arrayBuffer->memSpec,"CL_MEM_USE_HOST_PTR");
if (mask & CL_MEM_READ_WRITE) strcat(arg->arrayBuffer->memSpec,"|CL_MEM_READ_WRITE");
@@ -381,7 +382,6 @@ void updateArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argP
// Add the array length if needed
if (arg->usesArrayLength()) {
argPos++;
- arg->syncJavaArrayLength(jenv);
status = clSetKernelArg(jniContext->kernel, argPos, sizeof(jint), &(arg->arrayBuffer->length));
if(status != CL_SUCCESS) throw CLException(status,"clSetKernelArg (array length)");
@@ -629,15 +629,39 @@ void updateWriteEvents(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int
void processLocalArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argPos, int argIdx) {
cl_int status = CL_SUCCESS;
- // what if local buffer size has changed? We need a check for resize here.
- if (jniContext->firstRun) {
+
+ cl_uint arrayLength;
+ int lengthInBytes;
+
+ arg->arrayBuffer->getMinimalParams(jenv, arg, arrayLength, lengthInBytes);
+
+ if (config->isVerbose()) {
+ fprintf(stderr, "runKernel local array arg %d %s - new[elems: %d, bytes: %d], old[elems: %d, bytes: %d]\n",
+ argIdx, arg->name, arrayLength, lengthInBytes, arg->arrayBuffer->length, arg->arrayBuffer->lengthInBytes);
+ }
+
+ bool changed = false;
+ if (lengthInBytes != arg->arrayBuffer->lengthInBytes) {
+ changed = true;
+ }
+
+ if (!changed && arg->usesArrayLength() && arrayLength != arg->arrayBuffer->length) {
+ changed = true;
+ }
+
+
+ if (jniContext->firstRun || changed) {
+ if (config->isVerbose()) {
+ fprintf(stderr, "runKernel local array arg %d %s resize detected - adjusting args\n", argIdx, arg->name);
+ }
+
+ arg->arrayBuffer->syncMinimalParams(jenv, arg);
+
status = arg->setLocalBufferArg(jenv, argIdx, argPos, config->isVerbose());
if(status != CL_SUCCESS) throw CLException(status,"clSetKernelArg() (local)");
// Add the array length if needed
if (arg->usesArrayLength()) {
- arg->syncJavaArrayLength(jenv);
-
status = clSetKernelArg(jniContext->kernel, argPos, sizeof(jint), &(arg->arrayBuffer->length));
if (config->isVerbose()){
@@ -645,9 +669,12 @@ void processLocalArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int
}
if(status != CL_SUCCESS) throw CLException(status,"clSetKernelArg (array length)");
-
}
} else {
+ if (config->isVerbose()) {
+ fprintf(stderr, "runKernel local array arg %d %s no resize detected - keeping args\n", argIdx, arg->name);
+ }
+
// Keep the arg position in sync if no updates were required
if (arg->usesArrayLength()) {
argPos++;
@@ -669,14 +696,43 @@ void processLocalArray(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int
void processLocalBuffer(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, int& argPos, int argIdx) {
cl_int status = CL_SUCCESS;
+
+ cl_uint numDims;
+ cl_uint dims[3];
+ int lengthInBytes;
+ arg->aparapiBuffer->getMinimalParams(jenv, arg, numDims, dims, lengthInBytes);
+
+ if (config->isVerbose()) {
+ fprintf(stderr, "runKernel local NDarray arg %d %s - new[bytes: %d], old[bytes: %d]\n",
+ argIdx, arg->name, lengthInBytes, arg->aparapiBuffer->lengthInBytes);
+ }
+
+
+ bool changed = false;
+ if (lengthInBytes != arg->aparapiBuffer->lengthInBytes) {
+ changed = true;
+ }
+
+ if (!changed && arg->usesArrayLength()) {
+ for (int i = 0; i < numDims; i++) {
+ if (dims[i] != arg->aparapiBuffer->lens[i]) {
+ changed = true;
+ break;
+ }
+ }
+ }
+
// what if local buffer size has changed? We need a check for resize here.
- if (jniContext->firstRun) {
+ if (jniContext->firstRun || changed) {
+ if (config->isVerbose()) {
+ fprintf(stderr, "runKernel local NDarray arg %d %s resize detected - adjusting args\n", argIdx, arg->name);
+ }
+
//To retrieve all fields of aparapiBuffer from Java for this local arg.
- arg->aparapiBuffer->flatten(jenv,arg);
+ arg->aparapiBuffer->syncMinimalParams(jenv, arg);
status = arg->setLocalAparapiBufferArg(jenv, argIdx, argPos, config->isVerbose());
if(status != CL_SUCCESS) {
- arg->aparapiBuffer->deleteBuffer(arg);
throw CLException(status,"clSetKernelArg() (local)");
}
@@ -684,36 +740,20 @@ void processLocalBuffer(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, in
if (arg->usesArrayLength()) {
for(int i = 0; i < arg->aparapiBuffer->numDims; i++)
{
- if (arg->aparapiBuffer->lens == NULL) {
- std::string str = "runKernel arg " + patch::to_string(argIdx) + " " + arg->name +
- " - AparapiBuffer lens field is NULL at dim " + patch::to_string(i+1) + " of " +
- patch::to_string(arg->aparapiBuffer->numDims) + "\n";
- arg->aparapiBuffer->deleteBuffer(arg);
- throw CLException(CL_INVALID_VALUE, str.c_str());
- }
int length = arg->aparapiBuffer->lens[i];
argPos++;
status = clSetKernelArg(jniContext->kernel, argPos, sizeof(cl_uint), &length);
if(status != CL_SUCCESS) {
- arg->aparapiBuffer->deleteBuffer(arg);
throw CLException(status,"clSetKernelArg (buffer length)");
}
if (config->isVerbose()){
fprintf(stderr, "runKernel arg %d %s, length = %d\n", argIdx, arg->name, length);
}
- if (arg->aparapiBuffer->offsets == NULL) {
- std::string str = "runKernel arg " + patch::to_string(argIdx) + " " + arg->name +
- " - AparapiBuffer offsets field is NULL at dim " + patch::to_string(i+1) + " of " +
- patch::to_string(arg->aparapiBuffer->numDims) + "\n";
- arg->aparapiBuffer->deleteBuffer(arg);
- throw CLException(CL_INVALID_VALUE, str.c_str());
- }
int offset = arg->aparapiBuffer->offsets[i];
argPos++;
status = clSetKernelArg(jniContext->kernel, argPos, sizeof(cl_uint), &offset);
if(status != CL_SUCCESS) {
- arg->aparapiBuffer->deleteBuffer(arg);
throw CLException(status,"clSetKernelArg (buffer offset)");
}
if (config->isVerbose()){
@@ -721,10 +761,14 @@ void processLocalBuffer(JNIEnv* jenv, JNIContext* jniContext, KernelArg* arg, in
}
}
}
- } else {
+ } else {
+ if (config->isVerbose()) {
+ fprintf(stderr, "runKernel local NDarray arg %d %s no resize detected - keeping args\n", argIdx, arg->name);
+ }
+
// Keep the arg position in sync if no updates were required
if (arg->usesArrayLength()) {
- argPos += arg->aparapiBuffer->numDims;
+ argPos += arg->aparapiBuffer->numDims*2;
}
}
}
@@ -970,14 +1014,6 @@ int getReadEvents(JNIEnv* jenv, JNIContext* jniContext) {
for (int i=0; i< jniContext->argc; i++) {
KernelArg *arg = jniContext->args[i];
- if (arg->isLocal() && arg->isAparapiBuffer()) {
- if (config->isVerbose()) {
- fprintf(stderr, "Freeing local aparapi buffer for arg %d", arg->name);
- }
- arg->aparapiBuffer->deleteBuffer(arg);
- continue;
- }
-
if (arg->needToEnqueueRead()){
if (arg->isConstant()){
fprintf(stderr, "reading %s\n", arg->name);
diff --git a/src/cpp/runKernel/AparapiBuffer.cpp b/src/cpp/runKernel/AparapiBuffer.cpp
index a6c29c784b601742c03f7ac2c81fd6c9adcd41d4..28cb6b2ee3e7daafddee71a259334f3e31e19635 100644
--- a/src/cpp/runKernel/AparapiBuffer.cpp
+++ b/src/cpp/runKernel/AparapiBuffer.cpp
@@ -42,35 +42,67 @@
AparapiBuffer::AparapiBuffer():
javaObject((jobject) 0),
numDims(0),
- offsets(NULL),
lengthInBytes(0),
mem((cl_mem) 0),
data(NULL),
memMask((cl_uint)0) {
+ for (int i = 0; i < MAX_ND_DIMS; i++) {
+ lens[i] = (cl_uint)0;
+ offsets[i] = (cl_uint)0;
+ }
}
AparapiBuffer::AparapiBuffer(void* _data, cl_uint* _lens, cl_uint _numDims, long _lengthInBytes, jobject _javaObject) :
data(_data),
- lens(_lens),
numDims(_numDims),
lengthInBytes(_lengthInBytes),
javaObject(_javaObject),
mem((cl_mem) 0),
memMask((cl_uint)0)
{
- offsets = new cl_uint[_numDims];
for(int i = 0; i < _numDims; i++) {
- offsets[i] = 1;
- for(int j = i+1; j < _numDims; j++) {
- offsets[i] *= lens[j];
- }
+ lens[i] = _lens[i];
+ }
+ computeOffsets();
+}
+
+void AparapiBuffer::computeOffsets() {
+ for(int i = 0; i < numDims; i++) {
+ offsets[i] = 1;
+ for(int j = i+1; j < numDims; j++) {
+ offsets[i] *= lens[j];
+ }
}
}
-jobject AparapiBuffer::getJavaObject(JNIEnv* env, KernelArg* arg) {
+jobject AparapiBuffer::getJavaObject(JNIEnv* env, KernelArg* arg) const {
return JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
}
+void AparapiBuffer::getMinimalParams(JNIEnv *env, KernelArg* arg, cl_uint &numDims, cl_uint dims[], int &lengthInBytes) const {
+ numDims = JNIHelper::getInstanceField<jint>(env, arg->javaArg, "numDims", IntArg);
+ jobjectArray jObjArray = (jobjectArray)getJavaObject(env, arg);
+ for (int i = 0; i < numDims; i++) {
+ dims[i] = env->GetArrayLength((jobjectArray)jObjArray);
+ if (i < numDims - 1) {
+ jObjArray = (jobjectArray)env->GetObjectArrayElement(jObjArray, 0);
+ }
+ }
+ lengthInBytes = env->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+}
+
+void AparapiBuffer::syncMinimalParams(JNIEnv *env, KernelArg* arg) {
+ numDims = JNIHelper::getInstanceField<jint>(env, arg->javaArg, "numDims", IntArg);
+ jobjectArray jObjArray = (jobjectArray)getJavaObject(env, arg);
+ for (int i = 0; i < numDims; i++) {
+ lens[i] = env->GetArrayLength((jobjectArray)jObjArray);
+ if (i < numDims - 1) {
+ jObjArray = (jobjectArray)env->GetObjectArrayElement(jObjArray, 0);
+ }
+ }
+ lengthInBytes = env->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+ computeOffsets();
+}
void AparapiBuffer::flatten(JNIEnv* env, KernelArg* arg) {
int numDims = JNIHelper::getInstanceField<jint>(env, arg->javaArg, "numDims", IntArg);
@@ -110,24 +142,20 @@ void AparapiBuffer::flatten(JNIEnv* env, KernelArg* arg) {
void AparapiBuffer::buildBuffer(void* _data, cl_uint* _dims, cl_uint _numDims, long _lengthInBytes, jobject _javaObject) {
data = _data;
- lens = _dims;
numDims = _numDims;
lengthInBytes = _lengthInBytes;
javaObject = _javaObject;
- offsets = new cl_uint[_numDims];
for(int i = 0; i < _numDims; i++) {
- offsets[i] = 1;
- for(int j = i+1; j < _numDims; j++) {
- offsets[i] *= lens[j];
- }
+ lens[i] = _dims[i];
}
+ computeOffsets();
}
void AparapiBuffer::flattenBoolean2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jbooleanArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -169,13 +197,13 @@ void AparapiBuffer::flattenBoolean2D(JNIEnv* env, KernelArg* arg) {
// env->DeleteLocalRef(jArray);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenByte2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jbyteArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -215,13 +243,13 @@ void AparapiBuffer::flattenByte2D(JNIEnv* env, KernelArg* arg) {
env->ReleaseByteArrayElements(jArray, elems, 0);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenShort2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jshortArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -261,13 +289,13 @@ void AparapiBuffer::flattenShort2D(JNIEnv* env, KernelArg* arg) {
env->ReleaseShortArrayElements(jArray, elems, 0);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenInt2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jintArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -307,13 +335,13 @@ void AparapiBuffer::flattenInt2D(JNIEnv* env, KernelArg* arg) {
env->ReleaseIntArrayElements(jArray, elems, 0);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenLong2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jlongArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -353,13 +381,13 @@ void AparapiBuffer::flattenLong2D(JNIEnv* env, KernelArg* arg) {
env->ReleaseLongArrayElements(jArray, elems, 0);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenFloat2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jfloatArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -399,13 +427,13 @@ void AparapiBuffer::flattenFloat2D(JNIEnv* env, KernelArg* arg) {
env->ReleaseFloatArrayElements(jArray, elems, 0);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenDouble2D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[2];
+ cl_uint dims[2];
dims[0] = env->GetArrayLength((jobjectArray)javaBuffer);
dims[1] = env->GetArrayLength((jdoubleArray)env->GetObjectArrayElement((jobjectArray)javaBuffer, 0));
int totalSize = dims[0] * dims[1];
@@ -445,14 +473,14 @@ void AparapiBuffer::flattenDouble2D(JNIEnv* env, KernelArg* arg) {
env->ReleaseDoubleArrayElements(jArray, elems, 0);
}
- buildBuffer((void*)array, (cl_uint*)dims, 2, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 2, bitSize, javaBuffer);
}
void AparapiBuffer::flattenBoolean3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jbooleanArray j2 = (jbooleanArray)env->GetObjectArrayElement(j1, 0);
@@ -510,13 +538,13 @@ void AparapiBuffer::flattenBoolean3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
void AparapiBuffer::flattenByte3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jbyteArray j2 = (jbyteArray)env->GetObjectArrayElement(j1, 0);
@@ -574,13 +602,13 @@ void AparapiBuffer::flattenByte3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
void AparapiBuffer::flattenShort3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jshortArray j2 = (jshortArray)env->GetObjectArrayElement(j1, 0);
@@ -638,13 +666,13 @@ void AparapiBuffer::flattenShort3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
void AparapiBuffer::flattenInt3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jintArray j2 = (jintArray)env->GetObjectArrayElement(j1, 0);
@@ -702,13 +730,13 @@ void AparapiBuffer::flattenInt3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
void AparapiBuffer::flattenLong3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jlongArray j2 = (jlongArray)env->GetObjectArrayElement(j1, 0);
@@ -766,13 +794,13 @@ void AparapiBuffer::flattenLong3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
void AparapiBuffer::flattenFloat3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jfloatArray j2 = (jfloatArray)env->GetObjectArrayElement(j1, 0);
@@ -830,13 +858,13 @@ void AparapiBuffer::flattenFloat3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
void AparapiBuffer::flattenDouble3D(JNIEnv* env, KernelArg* arg) {
jobject javaBuffer = JNIHelper::getInstanceField<jobject>(env, arg->javaArg, "javaBuffer", ObjectClassArg);
- cl_uint* dims = new cl_uint[3];
+ cl_uint dims[3];
jobjectArray j0 = (jobjectArray)javaBuffer;
jobjectArray j1 = (jobjectArray)env->GetObjectArrayElement(j0, 0);
jdoubleArray j2 = (jdoubleArray)env->GetObjectArrayElement(j1, 0);
@@ -894,7 +922,7 @@ void AparapiBuffer::flattenDouble3D(JNIEnv* env, KernelArg* arg) {
}
}
- buildBuffer((void*)array, (cl_uint*)dims, 3, bitSize, javaBuffer);
+ buildBuffer((void*)array, dims, 3, bitSize, javaBuffer);
}
@@ -1556,8 +1584,6 @@ void AparapiBuffer::inflateDouble3D(JNIEnv *env, KernelArg* arg) {
void AparapiBuffer::deleteBuffer(KernelArg* arg)
{
- delete[] offsets;
- delete[] lens;
if(arg->isBoolean()) {
delete[] (jboolean*)data;
} else if(arg->isByte()) {
diff --git a/src/cpp/runKernel/AparapiBuffer.h b/src/cpp/runKernel/AparapiBuffer.h
index 272cccffe0360bf3951d62b8a44ce583f59f5d4f..65f9a2043ff7412ad89fe3d90fa48a7e5609539e 100644
--- a/src/cpp/runKernel/AparapiBuffer.h
+++ b/src/cpp/runKernel/AparapiBuffer.h
@@ -72,21 +72,29 @@ private:
void buildBuffer(void* _data, cl_uint* _dims, cl_uint _numDims, long _lengthInBytes, jobject _javaObject);
+ void computeOffsets();
+
public:
- jobject javaObject; // The java array that this arg is mapped to
- cl_uint numDims; // number of dimensions of the object (array lengths for ND arrays)
- cl_uint* offsets; // offsets of the next element in ND arrays)
- cl_uint* lens; // sizes of dimensions of the object (array lengths for ND arrays)
- jint lengthInBytes; // bytes in the array or directBuf
- cl_mem mem; // the opencl buffer
- void *data; // a copy of the object itself (this is what we pass to OpenCL)
- cl_uint memMask; // the mask used for createBuffer
+ static int const MAX_ND_DIMS = 3;
+
+ jobject javaObject; // The java array that this arg is mapped to
+ cl_uint numDims; // number of dimensions of the object (array lengths for ND arrays)
+ cl_uint offsets[MAX_ND_DIMS]; // offsets of the next element in ND arrays) - Aparapi currently limits ND arrays to 3 dimensions
+ cl_uint lens[MAX_ND_DIMS]; // sizes of dimensions of the object (array lengths for ND arrays)
+ jint lengthInBytes; // bytes in the array or directBuf
+ cl_mem mem; // the opencl buffer
+ void *data; // a copy of the object itself (this is what we pass to OpenCL)
+ cl_uint memMask; // the mask used for createBuffer
ProfileInfo read;
ProfileInfo write;
AparapiBuffer();
AparapiBuffer(void* _data, cl_uint* _dims, cl_uint _numDims, long _lengthInBytes, jobject _javaObject);
+ void getMinimalParams(JNIEnv *env, KernelArg* arg, cl_uint &numDims, cl_uint dims[], int &lengthInBytes) const;
+
+ void syncMinimalParams(JNIEnv *env, KernelArg* arg);
+
void deleteBuffer(KernelArg* arg);
void flatten(JNIEnv *env, KernelArg* arg);
@@ -129,7 +137,7 @@ public:
void inflateFloat3D(JNIEnv *env, KernelArg* arg);
void inflateDouble3D(JNIEnv *env, KernelArg* arg);
- jobject getJavaObject(JNIEnv* env, KernelArg* arg);
+ jobject getJavaObject(JNIEnv* env, KernelArg* arg) const;
};
#endif // ARRAYBUFFER_H
diff --git a/src/cpp/runKernel/ArrayBuffer.cpp b/src/cpp/runKernel/ArrayBuffer.cpp
index b3947681371e6d756a35dadd94d09b223d215b03..21e11b67ea6c5e1ae1452cc50294b4f263b65d0c 100644
--- a/src/cpp/runKernel/ArrayBuffer.cpp
+++ b/src/cpp/runKernel/ArrayBuffer.cpp
@@ -37,6 +37,7 @@
*/
#define ARRAYBUFFER_SOURCE
#include "ArrayBuffer.h"
+#include "KernelArg.h"
ArrayBuffer::ArrayBuffer():
javaArray((jobject) 0),
@@ -62,3 +63,13 @@ void ArrayBuffer::pin(JNIEnv *jenv){
addr = jenv->GetPrimitiveArrayCritical((jarray)javaArray,&isCopy);
isPinned = JNI_TRUE;
}
+
+void ArrayBuffer::getMinimalParams(JNIEnv *jenv, KernelArg *arg, cl_uint& arrayElements, int &sizeInBytes) {
+ arrayElements = JNIHelper::getInstanceField<jint>(jenv, arg->javaArg, "numElements", IntArg);
+ sizeInBytes = jenv->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+}
+
+void ArrayBuffer::syncMinimalParams(JNIEnv *jenv, KernelArg *arg) {
+ length = JNIHelper::getInstanceField<jint>(jenv, arg->javaArg, "numElements", IntArg);
+ lengthInBytes = jenv->GetIntField(arg->javaArg, KernelArg::getSizeInBytesFieldID());
+}
diff --git a/src/cpp/runKernel/ArrayBuffer.h b/src/cpp/runKernel/ArrayBuffer.h
index 26f702c80f6819e0d544d8a6d831685f917490ba..9aff69813b56fffa71e05f23496c19ac068a5f99 100644
--- a/src/cpp/runKernel/ArrayBuffer.h
+++ b/src/cpp/runKernel/ArrayBuffer.h
@@ -41,6 +41,8 @@
#include "Common.h"
#include "ProfileInfo.h"
+class KernelArg;
+
class ArrayBuffer{
public:
jobject javaArray; // The java array that this arg is mapped to
@@ -59,6 +61,8 @@ class ArrayBuffer{
void unpinAbort(JNIEnv *jenv);
void unpinCommit(JNIEnv *jenv);
void pin(JNIEnv *jenv);
+ void getMinimalParams(JNIEnv *jenv, KernelArg *arg, cl_uint& arrayElements, int &sizeInBytes);
+ void syncMinimalParams(JNIEnv *jenv, KernelArg *arg);
};
#endif // ARRAYBUFFER_H
diff --git a/src/cpp/runKernel/KernelArg.h b/src/cpp/runKernel/KernelArg.h
index 9b0e433ea35087d982d2597af84da454583d792b..ed87a1b814e0305bdd04a9937371c5b7dfde07d0 100644
--- a/src/cpp/runKernel/KernelArg.h
+++ b/src/cpp/runKernel/KernelArg.h
@@ -61,7 +61,11 @@ class KernelArg{
public:
- static jfieldID javaArrayFieldID;
+ static jfieldID javaArrayFieldID;
+
+ static jfieldID getSizeInBytesFieldID(){
+ return sizeInBytesFieldID;
+ }
public:
JNIContext *jniContext;
jobject argObj; // the Java KernelRunner.KernelArg object that we are mirroring. Do not use it outside constructor due to GC. Use javaArg instead.
@@ -174,12 +178,15 @@ class KernelArg{
void syncType(JNIEnv* jenv){
type = jenv->GetIntField(javaArg, typeFieldID);
}
- void syncSizeInBytes(JNIEnv* jenv){
- arrayBuffer->lengthInBytes = jenv->GetIntField(javaArg, sizeInBytesFieldID);
+
+ int getSizeInBytes(JNIEnv* jenv){
+ return jenv->GetIntField(javaArg, sizeInBytesFieldID);
}
- void syncJavaArrayLength(JNIEnv* jenv){
- arrayBuffer->length = jenv->GetIntField(javaArg, numElementsFieldID);
+
+ cl_uint getJavaArrayLength(JNIEnv* jenv){
+ return jenv->GetIntField(javaArg, numElementsFieldID);
}
+
void clearExplicitBufferBit(JNIEnv* jenv){
type &= ~com_aparapi_internal_jni_KernelRunnerJNI_ARG_EXPLICIT_WRITE;
jenv->SetIntField(javaArg, typeFieldID,type );