From 49bef1c8c579c1bfb2f3e851b1ad8da2966122bd Mon Sep 17 00:00:00 2001
From: Gary Frost <frost.gary@gmail.com>
Date: Thu, 4 Jul 2013 19:59:27 +0000
Subject: [PATCH] Attempt to dispose bound kernel args for issue #120

---
 .../src/cpp/invoke/OpenCLJNI.cpp              | 28 +++++++++++++++++++
 .../com/amd/aparapi/device/OpenCLDevice.java  |  9 +++++-
 .../amd/aparapi/internal/jni/OpenCLJNI.java   |  2 ++
 .../aparapi/internal/opencl/OpenCLKernel.java |  4 +++
 .../sample/extension/SquareExample.java       |  2 ++
 5 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp b/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp
index ac065de3..e1ef0ef4 100644
--- a/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp
+++ b/com.amd.aparapi.jni/src/cpp/invoke/OpenCLJNI.cpp
@@ -250,6 +250,34 @@ void getArg(JNIEnv *jenv, cl_context context, cl_command_queue commandQueue, cl_
    }
 }
 
+JNI_JAVA(void, OpenCLJNI, dispose)
+   (JNIEnv *jenv, jobject jobj, jobject kernelInstance) {
+      cl_kernel kernel = OpenCLKernel::getKernel(jenv, kernelInstance);
+      jobject programInstance = OpenCLKernel::getProgramInstance(jenv, kernelInstance);
+      jobjectArray argDefsArray = OpenCLKernel::getArgsArray(jenv, kernelInstance);
+
+
+      cl_context context = OpenCLProgram::getContext(jenv, programInstance);
+      cl_command_queue commandQueue = OpenCLProgram::getCommandQueue(jenv, programInstance);
+      jsize argc = jenv->GetArrayLength(argDefsArray);
+      fprintf(stderr, "dispose! argc = %d\n", argc);
+      for (jsize argIndex = 0; argIndex < argc; argIndex++){
+         jobject argDef = jenv->GetObjectArrayElement(argDefsArray, argIndex);
+         jlong argBits = OpenCLArgDescriptor::getBits(jenv, argDef);
+         if (argisset(argBits, ARRAY) && argisset(argBits, GLOBAL)){
+            jobject memInstance = OpenCLArgDescriptor::getMemInstance(jenv, argDef);
+            if (memInstance == NULL){
+               fprintf(stderr, "mem instance not set\n");
+            }else{
+               cl_mem mem = OpenCLMem::getMem(jenv, memInstance);
+               size_t sizeInBytes = OpenCLMem::getSizeInBytes(jenv, memInstance);
+               cl_int status = clReleaseMemObject(mem); 
+               fprintf(stderr, "mem instance %d released!\n", sizeInBytes);
+            }
+         }
+      }
+   }
+
 /**
  */
 JNI_JAVA(void, OpenCLJNI, invoke)
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java b/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java
index 17a2a8d8..6e1cbc13 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/device/OpenCLDevice.java
@@ -167,7 +167,14 @@ public class OpenCLDevice extends Device{
             } else if (method.getName().equals("begin")) {
                System.out.println("begin not implemented");
             } else if (method.getName().equals("dispose")) {
-               System.out.println("dispose not implemented");
+               System.out.println("dispose");
+               for (OpenCLKernel k:map.values()){
+                   k.dispose();
+               }
+              // args =  map.get(method.getName());
+              // for (OpenCLArgDescriptor argDescriptor:args){
+
+              // }
             } else if (method.getName().equals("end")) {
                System.out.println("end not implemented");
             }
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java
index 42367320..34fd7edc 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/OpenCLJNI.java
@@ -22,6 +22,8 @@ public abstract class OpenCLJNI{
 
    protected native void invoke(OpenCLKernel openCLKernel, Object[] args);
 
+   protected native void dispose(OpenCLKernel openCLKernel);
+
    protected native void remap(OpenCLProgram program, OpenCLMem mem, long address);
 
    protected native byte[] getBytes(String className);
diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java
index 78c3eb22..04a95501 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/opencl/OpenCLKernel.java
@@ -56,4 +56,8 @@ public class OpenCLKernel extends OpenCLJNI{
    public void invoke(Object[] _args) {
       invoke(this, _args);
    }
+
+   public void dispose(){
+       dispose(this);
+   }
 }
diff --git a/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java b/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java
index d384b77a..cce44e44 100644
--- a/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java
+++ b/samples/extension/src/com/amd/aparapi/sample/extension/SquareExample.java
@@ -69,6 +69,8 @@ public class SquareExample{
          for (int i = 0; i < size; i++) {
             System.out.println(in[i] + " " + squares[i] + " " + quads[i]);
          }
+
+         squarer.dispose();
       }
    }
 }
-- 
GitLab