[Android] mem ptr to byte-buffer accepted/tizen/unified/20200813.122616 submit/tizen/20200813.010849
authorJaeyun <jy1210.jung@samsung.com>
Wed, 5 Aug 2020 11:29:21 +0000 (20:29 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Wed, 12 Aug 2020 12:32:25 +0000 (21:32 +0900)
In native code, we can get the mem ptr of byte-buffer.
Remove memcopy to convert tensors object and data struct in native.

Signed-off-by: Jaeyun <jy1210.jung@samsung.com>
api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsData.java
api/android/api/src/main/jni/nnstreamer-native-api.c
api/android/api/src/main/jni/nnstreamer-native-customfilter.c
api/android/api/src/main/jni/nnstreamer-native-pipeline.c
api/android/api/src/main/jni/nnstreamer-native-singleshot.c
api/android/api/src/main/jni/nnstreamer-native.h

index 9f081f1..452666a 100644 (file)
@@ -105,25 +105,6 @@ public final class TensorsData implements AutoCloseable {
     /**
      * Adds a new tensor data.
      *
-     * @param data The byte array to be added
-     *
-     * @throws IllegalArgumentException if given data is invalid
-     * @throws IndexOutOfBoundsException when the maximum number of tensors in the list
-     */
-    private void addTensorData(@NonNull byte[] data) {
-        if (data == null) {
-            throw new IllegalArgumentException("Given data is null");
-        }
-
-        ByteBuffer buffer = allocateByteBuffer(data.length);
-        buffer.put(data);
-
-        addTensorData(buffer);
-    }
-
-    /**
-     * Adds a new tensor data.
-     *
      * @param data The tensor data to be added
      *
      * @throws IllegalArgumentException if given data is invalid
@@ -132,8 +113,12 @@ public final class TensorsData implements AutoCloseable {
     private void addTensorData(@NonNull ByteBuffer data) {
         int index = getTensorsCount();
 
-        checkByteBuffer(index, data);
+        if (data.isDirect() && data.order() != ByteOrder.nativeOrder()) {
+            /* From native function NewDirectByteBuffer(), we should change the byte order. */
+            data = data.order(ByteOrder.nativeOrder());
+        }
 
+        checkByteBuffer(index, data);
         mDataList.add(data);
     }
 
index 642f15f..49d15f2 100644 (file)
@@ -162,7 +162,7 @@ nns_construct_tdata_class_info (JNIEnv * env, data_class_info_s * info)
   info->mid_init = (*env)->GetMethodID (env, info->cls, "<init>",
       "(L" NNS_CLS_TINFO ";)V");
   info->mid_add_data = (*env)->GetMethodID (env, info->cls, "addTensorData",
-      "([B)V");
+      "(Ljava/nio/ByteBuffer;)V");
   info->mid_get_array = (*env)->GetMethodID (env, info->cls, "getDataArray",
       "()[Ljava/lang/Object;");
   info->mid_get_info = (*env)->GetMethodID (env, info->cls, "getTensorsInfo",
@@ -408,11 +408,9 @@ nns_convert_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env,
   }
 
   for (i = 0; i < data->num_tensors; i++) {
-    jsize buffer_size = (jsize) data->tensors[i].size;
-    jbyteArray buffer = (*env)->NewByteArray (env, buffer_size);
-
-    (*env)->SetByteArrayRegion (env, buffer, 0, buffer_size,
-        (jbyte *) data->tensors[i].tensor);
+    gsize data_size = data->tensors[i].size;
+    gpointer data_ptr = data->tensors[i].tensor;
+    jobject buffer = (*env)->NewDirectByteBuffer (env, data_ptr, data_size);
 
     (*env)->CallVoidMethod (env, obj_data, dcls_info->mid_add_data, buffer);
     (*env)->DeleteLocalRef (env, buffer);
@@ -428,7 +426,7 @@ done:
  */
 gboolean
 nns_parse_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env,
-    jobject obj_data, ml_tensors_data_h * data_h, ml_tensors_info_h * info_h)
+    jobject obj_data, gboolean clone, ml_tensors_data_h * data_h, ml_tensors_info_h * info_h)
 {
   guint i;
   data_class_info_s *dcls_info;
@@ -463,19 +461,22 @@ nns_parse_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env,
       gsize data_size = (gsize) (*env)->GetDirectBufferCapacity (env, tensor);
       gpointer data_ptr = (*env)->GetDirectBufferAddress (env, tensor);
 
-      if (data->tensors[i].tensor == NULL)
-        data->tensors[i].tensor = g_malloc (data_size);
-      if (data->tensors[i].tensor == NULL) {
-        nns_loge ("Failed to allocate memory %zd, index %d.", data_size, i);
-        (*env)->DeleteLocalRef (env, tensor);
-        failed = TRUE;
-        goto done;
+      if (clone) {
+        if (data->tensors[i].tensor == NULL)
+          data->tensors[i].tensor = g_malloc (data_size);
+
+        memcpy (data->tensors[i].tensor, data_ptr, data_size);
+      } else {
+        data->tensors[i].tensor = data_ptr;
       }
 
-      memcpy (data->tensors[i].tensor, data_ptr, data_size);
       data->tensors[i].size = data_size;
 
       (*env)->DeleteLocalRef (env, tensor);
+    } else {
+      nns_loge ("Failed to get array element in tensors data object.");
+      failed = TRUE;
+      goto done;
     }
   }
 
index 698cd89..de36284 100644 (file)
@@ -127,7 +127,7 @@ nns_customfilter_invoke (const ml_tensors_data_h in, ml_tensors_data_h out,
     goto done;
   }
 
-  if (!nns_parse_tensors_data (pipe_info, env, obj_out_data, &out, NULL)) {
+  if (!nns_parse_tensors_data (pipe_info, env, obj_out_data, TRUE, &out, NULL)) {
     nns_loge ("Failed to parse output data.");
     goto done;
   }
index 7ebacdd..0a94b32 100644 (file)
@@ -516,13 +516,13 @@ nns_native_pipe_input_data (JNIEnv * env, jobject thiz, jlong handle,
     goto done;
   }
 
-  if (!nns_parse_tensors_data (pipe_info, env, in, &in_data, NULL)) {
+  if (!nns_parse_tensors_data (pipe_info, env, in, FALSE, &in_data, NULL)) {
     nns_loge ("Failed to parse input data.");
     goto done;
   }
 
   status = ml_pipeline_src_input_data (src, in_data,
-      ML_PIPELINE_BUF_POLICY_AUTO_FREE);
+      ML_PIPELINE_BUF_POLICY_DO_NOT_FREE);
   if (status != ML_ERROR_NONE) {
     nns_loge ("Failed to input tensors data to source node %s.", element_name);
     goto done;
@@ -532,6 +532,8 @@ nns_native_pipe_input_data (JNIEnv * env, jobject thiz, jlong handle,
 
 done:
   (*env)->ReleaseStringUTFChars (env, name, element_name);
+  /* do not free input tensors (direct access from object) */
+  g_free (in_data);
   return res;
 }
 
index 257fec4..a2bc2c6 100644 (file)
@@ -225,7 +225,7 @@ nns_native_single_invoke (JNIEnv * env, jobject thiz, jlong handle, jobject in)
   single = pipe_info->pipeline_handle;
   in_data = out_data = NULL;
 
-  if (!nns_parse_tensors_data (pipe_info, env, in, &in_data, NULL)) {
+  if (!nns_parse_tensors_data (pipe_info, env, in, FALSE, &in_data, NULL)) {
     nns_loge ("Failed to parse input tensors data.");
     goto done;
   }
@@ -242,7 +242,8 @@ nns_native_single_invoke (JNIEnv * env, jobject thiz, jlong handle, jobject in)
   }
 
 done:
-  ml_tensors_data_destroy (in_data);
+  /* do not free input tensors (direct access from object) */
+  g_free (in_data);
   ml_tensors_data_destroy (out_data);
   return result;
 }
index 2e3449d..d0fa82b 100644 (file)
@@ -208,7 +208,7 @@ nns_convert_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env, ml_tensors_
  * @brief Parse tensors data from TensorsData object.
  */
 extern gboolean
-nns_parse_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env, jobject obj_data, ml_tensors_data_h * data_h, ml_tensors_info_h * info_h);
+nns_parse_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env, jobject obj_data, gboolean clone, ml_tensors_data_h * data_h, ml_tensors_info_h * info_h);
 
 /**
  * @brief Convert tensors info to TensorsInfo object.