[Common] prepare 0-init dimension
authorJaeyun Jung <jy1210.jung@samsung.com>
Fri, 19 May 2023 07:17:18 +0000 (16:17 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Tue, 30 May 2023 06:33:26 +0000 (15:33 +0900)
Prepare increasing max rank and 0-init dimension case.

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
gst/nnstreamer/include/nnstreamer_plugin_api_util.h
gst/nnstreamer/nnstreamer_plugin_api_util_impl.c
gst/nnstreamer/tensor_filter/tensor_filter_common.c
tests/common/unittest_common.cc

index 0c2e4b2..6fb311c 100644 (file)
@@ -626,12 +626,18 @@ TFLiteInterpreter::getTensorDim (int tensor_idx, tensor_dim dim)
 {
   TfLiteIntArray *tensor_dims = interpreter->tensor (tensor_idx)->dims;
   int len = tensor_dims->size;
+
+  /* 0-init */
+  for (guint i = 0; i < NNS_TENSOR_RANK_LIMIT; ++i)
+    dim[i] = 0;
+
   if (len > NNS_TENSOR_RANK_LIMIT)
     return -EPERM;
 
   /* the order of dimension is reversed at CAPS negotiation */
   std::reverse_copy (tensor_dims->data, tensor_dims->data + len, dim);
 
+  /** @todo remove below lines (dno not fill 1) */
   /* fill the remnants with 1 */
   for (int i = len; i < NNS_TENSOR_RANK_LIMIT; ++i) {
     dim[i] = 1;
@@ -730,8 +736,12 @@ TFLiteInterpreter::setInputTensorsInfo (const GstTensorsInfo *info)
      * iterate over all possible ranks starting from MIN rank to the actual rank
      * of the dimension array. In case of none of these ranks work, return error
      */
-    input_rank = gst_tensor_info_get_rank (tensor_info);
-    for (int rank = input_rank; rank <= NNS_TENSOR_RANK_LIMIT; rank++) {
+    for (input_rank = NNS_TENSOR_RANK_LIMIT - 1; input_rank > 0; input_rank--) {
+      if (tensor_info->dimension[input_rank] > 1)
+        break;
+    }
+
+    for (int rank = input_rank + 1; rank <= NNS_TENSOR_RANK_LIMIT; rank++) {
       std::vector<int> dims (rank);
       /* the order of dimension is reversed at CAPS negotiation */
       for (int idx = 0; idx < rank; idx++) {
index a25bc7a..a010b94 100644 (file)
@@ -91,7 +91,7 @@ gst_tensor_info_convert_to_meta (GstTensorInfo * info, GstTensorMetaInfo * meta)
  * @param info tensor info structure
  * @return tensor rank (Minimum rank is 1 if given info is valid)
  */
-extern gint
+extern guint
 gst_tensor_info_get_rank (const GstTensorInfo * info);
 
 /**
@@ -290,6 +290,14 @@ extern gboolean
 gst_tensor_dimension_is_equal (const tensor_dim dim1, const tensor_dim dim2);
 
 /**
+ * @brief Get the rank of tensor dimension.
+ * @param dim tensor dimension.
+ * @return tensor rank (Minimum rank is 1 if given info is valid)
+ */
+extern guint
+gst_tensor_dimension_get_rank (const tensor_dim dim);
+
+/**
  * @brief Parse tensor dimension parameter string
  * @return The Rank. 0 if error.
  * @param dimstr The dimension string in the format of d1:...:d8, d1:d2:d3, d1:d2, or d1, where dN is a positive integer and d1 is the innermost dimension; i.e., dim[d8][d7][d6][d5][d4][d3][d2][d1];
index 8f89ac5..25f3577 100644 (file)
@@ -208,12 +208,10 @@ gst_tensor_info_is_equal (const GstTensorInfo * i1, const GstTensorInfo * i2)
   }
 
   if (!gst_tensor_dimension_is_equal (i1->dimension, i2->dimension)) {
-    gchar *dim_str1 = gst_tensor_get_dimension_string (i1->dimension);
-    gchar *dim_str2 = gst_tensor_get_dimension_string (i2->dimension);
+    g_autofree gchar *_dim1 = gst_tensor_get_dimension_string (i1->dimension);
+    g_autofree gchar *_dim2 = gst_tensor_get_dimension_string (i2->dimension);
     nns_logd ("Tensor info is not equal. Given tensor dimensions %s vs %s",
-        dim_str1, dim_str2);
-    g_free (dim_str1);
-    g_free (dim_str2);
+        _dim1, _dim2);
     return FALSE;
   }
 
@@ -286,7 +284,7 @@ gst_tensor_info_convert_to_meta (GstTensorInfo * info, GstTensorMetaInfo * meta)
  * @param info tensor info structure
  * @return tensor rank (Minimum rank is 1 if given info is valid)
  */
-gint
+guint
 gst_tensor_info_get_rank (const GstTensorInfo * info)
 {
   gint idx;
@@ -298,7 +296,7 @@ gst_tensor_info_get_rank (const GstTensorInfo * info)
     if (info->dimension[idx] != 1)
       break;
   }
-
+  /** @todo use gst_tensor_dimension_get_rank (info->dimension) after 0-init dim is done */
   return idx + 1;
 }
 
@@ -987,22 +985,28 @@ gboolean
 gst_tensor_dimension_is_valid (const tensor_dim dim)
 {
   guint i;
+  gboolean is_valid = FALSE;
 
-  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; ++i) {
-    if (dim[i] == 0) {
-      gchar *dim_str = gst_tensor_get_dimension_string (dim);
-      nns_logd
-          ("Failed to validate tensor dimension. Given dimension: %s. The dimension string should be in the form of d1:...:d8, d1:d2:d3:d4, d1:d2:d3, d1:d2, or d1. Here, dN is a positive integer.",
-          dim_str);
-      _nnstreamer_error_write
-          ("Failed to validate tensor dimension. Given dimension: %s. The dimension string should be in the form of d1:...:d8, d1:d2:d3:d4, d1:d2:d3, d1:d2, or d1. Here, dN is a positive integer.",
-          dim_str);
-      g_free (dim_str);
-      return FALSE;
-    }
+  i = gst_tensor_dimension_get_rank (dim);
+  if (i == 0)
+    goto done;
+
+  for (; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    if (dim[i] > 0)
+      goto done;
   }
 
-  return TRUE;
+  is_valid = TRUE;
+
+done:
+  if (!is_valid) {
+    nns_logd
+        ("Failed to validate tensor dimension. The dimension string should be in the form of d1:...:d8, d1:d2:d3:d4, d1:d2:d3, d1:d2, or d1. Here, dN is a positive integer.");
+    _nnstreamer_error_write
+        ("Failed to validate tensor dimension. The dimension string should be in the form of d1:...:d8, d1:d2:d3:d4, d1:d2:d3, d1:d2, or d1. Here, dN is a positive integer.");
+  }
+
+  return is_valid;
 }
 
 /**
@@ -1019,14 +1023,46 @@ gst_tensor_dimension_is_equal (const tensor_dim dim1, const tensor_dim dim2)
     return FALSE;
 
   for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
-    if (dim1[i] != dim2[i])
-      return FALSE;
+    if (dim1[i] != dim2[i]) {
+      const tensor_dim *remained;
+
+      if (dim1[i] == 0U)
+        remained = (const tensor_dim *) &dim2;
+      else if (dim2[i] == 0U)
+        remained = (const tensor_dim *) &dim1;
+      else
+        return FALSE;
+
+      /* Supposed dimension is same if remained dimension is 1. */
+      for (; i < NNS_TENSOR_RANK_LIMIT; i++) {
+        if ((*remained)[i] > 1)
+          return FALSE;
+      }
+    }
   }
 
   return TRUE;
 }
 
 /**
+ * @brief Get the rank of tensor dimension.
+ * @param dim tensor dimension.
+ * @return tensor rank (Minimum rank is 1 if given dimension is valid)
+ */
+guint
+gst_tensor_dimension_get_rank (const tensor_dim dim)
+{
+  guint i;
+
+  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    if (dim[i] == 0)
+      break;
+  }
+
+  return i;
+}
+
+/**
  * @brief Parse tensor dimension parameter string
  * @return The Rank. 0 if error.
  * @param dimstr The dimension string in the format of d1:...:d8, d1:d2:d3, d1:d2, or d1, where dN is a positive integer and d1 is the innermost dimension; i.e., dim[d8][d7][d6][d5][d4][d3][d2][d1];
@@ -1065,6 +1101,10 @@ gst_tensor_parse_dimension (const gchar * dimstr, tensor_dim dim)
     rank = i + 1;
   }
 
+  /**
+   * @todo remove below lines
+   * (0-initialized before parsing the string, filled remained dimension with 0)
+   */
   for (; i < NNS_TENSOR_RANK_LIMIT; i++)
     dim[i] = 1;
 
@@ -1109,9 +1149,12 @@ gst_tensor_get_rank_dimension_string (const tensor_dim dim,
     actual_rank = rank;
 
   for (i = 0; i < actual_rank; i++) {
+    if (dim[i] == 0)
+      break;
+
     g_string_append_printf (dim_str, "%u", dim[i]);
 
-    if (i < actual_rank - 1) {
+    if (i < actual_rank - 1 && dim[i + 1] > 0) {
       g_string_append (dim_str, ":");
     }
   }
@@ -1149,10 +1192,8 @@ gst_tensor_dimension_string_is_equal (const gchar * dimstr1,
     rank1 = gst_tensor_parse_dimension (strv1[i], dim1);
     rank2 = gst_tensor_parse_dimension (strv2[i], dim2);
 
-    if (!rank1 || !rank2)
-      goto done;
-
-    if (!gst_tensor_dimension_is_equal (dim1, dim2))
+    /* 'rank 0' means invalid dimension */
+    if (!rank1 || !rank2 || !gst_tensor_dimension_is_equal (dim1, dim2))
       goto done;
   }
 
@@ -1178,10 +1219,13 @@ gst_tensor_get_element_count (const tensor_dim dim)
   guint i;
 
   for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    if (dim[i] == 0)
+      break;
+
     count *= dim[i];
   }
 
-  return count;
+  return (i > 0) ? count : 0;
 }
 
 /**
@@ -1559,7 +1603,7 @@ gst_tensor_meta_info_convert (GstTensorMetaInfo * meta, GstTensorInfo * info)
       break;
     }
 
-    /** @todo handle rank from info.dimension */
+    /** @todo handle rank from info.dimension (Fill 0, not 1) */
     info->dimension[i] = (meta->dimension[i] > 0) ? meta->dimension[i] : 1;
   }
 
index afffd4a..8061e5f 100644 (file)
@@ -263,7 +263,7 @@ gst_tensor_filter_get_rank_string (const GstTensorFilterProperties * prop,
       if (_ranks[i] != 0)
         g_string_append_printf (rank, "%u", _ranks[i]);
       else
-        g_string_append_printf (rank, "%d",
+        g_string_append_printf (rank, "%u",
             gst_tensor_info_get_rank (&_meta->info[i]));
 
       if (i < _meta->num_tensors - 1)
index 9ce776f..5770e79 100644 (file)
@@ -767,7 +767,7 @@ TEST (commonTensorsInfo, equalInvalidParam1_n)
  */
 TEST (commonTensorInfo, getrankInvalidParam0_n)
 {
-  EXPECT_EQ (0, gst_tensor_info_get_rank (NULL));
+  EXPECT_EQ (0U, gst_tensor_info_get_rank (NULL));
 }
 
 /**