[common] Add utils for extra tensor_info
authorYongjoo Ahn <yongjoo1.ahn@samsung.com>
Wed, 21 Jun 2023 08:22:48 +0000 (17:22 +0900)
committerYongjoo Ahn <yongjoo1.ahn@samsung.com>
Thu, 20 Jul 2023 04:48:06 +0000 (13:48 +0900)
- Add util functions for extra `ml_tensor_info_s`.
- Replace index based access of tensor_info with newly added util
  `gst_tensors_info_get_nth_info` and `ml_tensors_info_get_nth_info`

Signed-off-by: Yongjoo Ahn <yongjoo1.ahn@samsung.com>
c/src/ml-api-common.c
c/src/ml-api-inference-internal.c
c/src/ml-api-inference-pipeline.c
c/src/ml-api-inference-single.c
c/src/ml-api-internal.h

index 7610d99..047a697 100644 (file)
@@ -114,12 +114,68 @@ ml_tensors_info_destroy (ml_tensors_info_h info)
 }
 
 /**
+ * @brief Allocates memory in given tensors_info for extra tensor infos.
+ */
+gboolean
+_ml_tensors_info_create_extra (ml_tensors_info_s * ml_info)
+{
+  ml_tensor_info_s *new;
+  guint i;
+
+  if (!ml_info)
+    _ml_error_report_return (FALSE, "The parameter, ml_info, is NULL.");
+
+  if (ml_info->extra) {
+    return TRUE;
+  }
+
+  new = g_try_new0 (ml_tensor_info_s, ML_TENSOR_SIZE_EXTRA_LIMIT);
+  if (!new) {
+    _ml_loge ("Failed to allocate memory for extra tensors info.");
+    return FALSE;
+  }
+
+  for (i = 0; i < ML_TENSOR_SIZE_EXTRA_LIMIT; i++) {
+    if (_ml_tensor_info_initialize (&new[i]) != ML_ERROR_NONE) {
+      _ml_loge ("Failed to initialize extra tensors info.");
+      g_free (new);
+      return FALSE;
+    }
+  }
+
+  ml_info->extra = new;
+
+  return TRUE;
+}
+
+/**
+ * @brief Initializes given tensor_info with default value.
+ */
+int
+_ml_tensor_info_initialize (ml_tensor_info_s * info)
+{
+  guint i;
+
+  if (!info)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, info, is NULL. Provide a valid pointer.");
+
+  info->name = NULL;
+  info->type = ML_TENSOR_TYPE_UNKNOWN;
+  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
+    info->dimension[i] = 0;
+  }
+
+  return ML_ERROR_NONE;
+}
+
+/**
  * @brief Initializes the tensors information with default value.
  */
 int
 _ml_tensors_info_initialize (ml_tensors_info_s * info)
 {
-  guint i, j;
+  guint i;
 
   if (!info)
     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
@@ -127,19 +183,40 @@ _ml_tensors_info_initialize (ml_tensors_info_s * info)
 
   info->num_tensors = 0;
 
-  for (i = 0; i < ML_TENSOR_SIZE_LIMIT; i++) {
-    info->info[i].name = NULL;
-    info->info[i].type = ML_TENSOR_TYPE_UNKNOWN;
-
-    for (j = 0; j < ML_TENSOR_RANK_LIMIT; j++) {
-      info->info[i].dimension[j] = 0;
-    }
+  for (i = 0; i < ML_TENSOR_SIZE_LIMIT_STATIC; i++) {
+    _ml_tensor_info_initialize (&info->info[i]);
   }
 
+  info->extra = NULL;
+
   return ML_ERROR_NONE;
 }
 
 /**
+ * @brief Get the pointer of nth tensor info.
+ */
+ml_tensor_info_s *
+ml_tensors_info_get_nth_info (ml_tensors_info_s * info, guint nth)
+{
+  if (!info)
+    return NULL;
+
+  if (nth >= ML_TENSOR_SIZE_LIMIT) {
+    _ml_loge ("The given nth is out of range. It should be less than %d.",
+        ML_TENSOR_SIZE_LIMIT);
+    return NULL;
+  }
+
+  if (nth < ML_TENSOR_SIZE_LIMIT_STATIC)
+    return &info->info[nth];
+
+  if (!_ml_tensors_info_create_extra (info))
+    return NULL;
+
+  return &info->extra[nth - ML_TENSOR_SIZE_LIMIT_STATIC];
+}
+
+/**
  * @brief Compares the given tensor info.
  */
 static gboolean
@@ -215,7 +292,9 @@ _ml_tensors_info_validate_nolock (const ml_tensors_info_s * info, bool *valid)
   }
 
   for (i = 0; i < info->num_tensors; i++) {
-    if (!ml_tensor_info_validate (&info->info[i], info->is_extended))
+    ml_tensor_info_s *tensor_info =
+        ml_tensors_info_get_nth_info ((ml_tensors_info_s *) info, i);
+    if (!ml_tensor_info_validate (tensor_info, info->is_extended))
       goto done;
   }
 
@@ -291,7 +370,9 @@ _ml_tensors_info_compare (const ml_tensors_info_h info1,
     goto done;
 
   for (i = 0; i < i1->num_tensors; i++) {
-    if (!ml_tensor_info_compare (&i1->info[i], &i2->info[i], i1->is_extended))
+    ml_tensor_info_s *ti1 = ml_tensors_info_get_nth_info (i1, i);
+    ml_tensor_info_s *ti2 = ml_tensors_info_get_nth_info (i2, i);
+    if (!ml_tensor_info_compare (ti1, ti2, i1->is_extended))
       goto done;
   }
 
@@ -318,8 +399,8 @@ ml_tensors_info_set_count (ml_tensors_info_h info, unsigned int count)
         "The parameter, info, is NULL. It should be a valid ml_tensors_info_h handle, which is usually created by ml_tensors_info_create().");
   if (count > ML_TENSOR_SIZE_LIMIT || count == 0)
     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
-        "The parameter, count, is the number of tensors, which should be between 1 and 16. The given count is %u.",
-        count);
+        "The parameter, count, is the number of tensors, which should be between 1 and %d. The given count is %u.",
+        ML_TENSOR_SIZE_LIMIT, count);
 
   tensors_info = (ml_tensors_info_s *) info;
 
@@ -361,6 +442,7 @@ ml_tensors_info_set_tensor_name (ml_tensors_info_h info,
     unsigned int index, const char *name)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
 
   check_feature_state (ML_FEATURE);
 
@@ -378,13 +460,19 @@ ml_tensors_info_set_tensor_name (ml_tensors_info_h info,
         tensors_info->num_tensors, index);
   }
 
-  if (tensors_info->info[index].name) {
-    g_free (tensors_info->info[index].name);
-    tensors_info->info[index].name = NULL;
+  _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+  if (!_tensor_info) {
+    G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+    return ML_ERROR_INVALID_PARAMETER;
+  }
+
+  if (_tensor_info->name) {
+    g_free (_tensor_info->name);
+    _tensor_info->name = NULL;
   }
 
   if (name)
-    tensors_info->info[index].name = g_strdup (name);
+    _tensor_info->name = g_strdup (name);
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
   return ML_ERROR_NONE;
@@ -398,6 +486,7 @@ ml_tensors_info_get_tensor_name (ml_tensors_info_h info,
     unsigned int index, char **name)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
 
   check_feature_state (ML_FEATURE);
 
@@ -418,7 +507,14 @@ ml_tensors_info_get_tensor_name (ml_tensors_info_h info,
         tensors_info->num_tensors, index);
   }
 
-  *name = g_strdup (tensors_info->info[index].name);
+  _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+  if (!_tensor_info) {
+    G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+    return ML_ERROR_INVALID_PARAMETER;
+  }
+
+  *name = g_strdup (_tensor_info->name);
+
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
   return ML_ERROR_NONE;
@@ -432,6 +528,7 @@ ml_tensors_info_set_tensor_type (ml_tensors_info_h info,
     unsigned int index, const ml_tensor_type_e type)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
 
   check_feature_state (ML_FEATURE);
 
@@ -459,7 +556,13 @@ ml_tensors_info_set_tensor_type (ml_tensors_info_h info,
     return ML_ERROR_INVALID_PARAMETER;
   }
 
-  tensors_info->info[index].type = type;
+  _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+  if (!_tensor_info) {
+    G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+    return ML_ERROR_INVALID_PARAMETER;
+  }
+
+  _tensor_info->type = type;
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
   return ML_ERROR_NONE;
@@ -473,6 +576,7 @@ ml_tensors_info_get_tensor_type (ml_tensors_info_h info,
     unsigned int index, ml_tensor_type_e * type)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
 
   check_feature_state (ML_FEATURE);
 
@@ -491,7 +595,12 @@ ml_tensors_info_get_tensor_type (ml_tensors_info_h info,
     return ML_ERROR_INVALID_PARAMETER;
   }
 
-  *type = tensors_info->info[index].type;
+  _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+  if (!_tensor_info) {
+    G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+    return ML_ERROR_INVALID_PARAMETER;
+  }
+  *type = _tensor_info->type;
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
   return ML_ERROR_NONE;
@@ -505,6 +614,7 @@ ml_tensors_info_set_tensor_dimension (ml_tensors_info_h info,
     unsigned int index, const ml_tensor_dimension dimension)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
   guint i;
 
   check_feature_state (ML_FEATURE);
@@ -523,13 +633,18 @@ ml_tensors_info_set_tensor_dimension (ml_tensors_info_h info,
         tensors_info->num_tensors, index, index);
   }
 
+  _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+  if (!_tensor_info) {
+    G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+    return ML_ERROR_INVALID_PARAMETER;
+  }
+
   for (i = 0; i < ML_TENSOR_RANK_LIMIT_PREV; i++) {
-    tensors_info->info[index].dimension[i] = dimension[i];
+    _tensor_info->dimension[i] = dimension[i];
   }
 
   for (i = ML_TENSOR_RANK_LIMIT_PREV; i < ML_TENSOR_RANK_LIMIT; i++) {
-    tensors_info->info[index].dimension[i] =
-        (tensors_info->is_extended ? dimension[i] : 1);
+    _tensor_info->dimension[i] = (tensors_info->is_extended ? dimension[i] : 1);
   }
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
@@ -544,6 +659,7 @@ ml_tensors_info_get_tensor_dimension (ml_tensors_info_h info,
     unsigned int index, ml_tensor_dimension dimension)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
   guint i, valid_rank = ML_TENSOR_RANK_LIMIT;
 
   check_feature_state (ML_FEATURE);
@@ -560,11 +676,17 @@ ml_tensors_info_get_tensor_dimension (ml_tensors_info_h info,
     return ML_ERROR_INVALID_PARAMETER;
   }
 
+  _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+  if (!_tensor_info) {
+    G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+    return ML_ERROR_INVALID_PARAMETER;
+  }
+
   if (!tensors_info->is_extended)
     valid_rank = ML_TENSOR_RANK_LIMIT_PREV;
 
   for (i = 0; i < valid_rank; i++) {
-    dimension[i] = tensors_info->info[index].dimension[i];
+    dimension[i] = _tensor_info->dimension[i];
   }
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
@@ -626,6 +748,7 @@ ml_tensors_info_get_tensor_size (ml_tensors_info_h info,
     int index, size_t *data_size)
 {
   ml_tensors_info_s *tensors_info;
+  ml_tensor_info_s *_tensor_info;
 
   check_feature_state (ML_FEATURE);
 
@@ -647,11 +770,20 @@ ml_tensors_info_get_tensor_size (ml_tensors_info_h info,
 
     /* get total byte size */
     for (i = 0; i < tensors_info->num_tensors; i++) {
+      _tensor_info = ml_tensors_info_get_nth_info (tensors_info, i);
+      if (!_tensor_info) {
+        G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+        return ML_ERROR_INVALID_PARAMETER;
+      }
       *data_size +=
-          _ml_tensor_info_get_size (&tensors_info->info[i],
-          tensors_info->is_extended);
+          _ml_tensor_info_get_size (_tensor_info, tensors_info->is_extended);
     }
   } else {
+    _tensor_info = ml_tensors_info_get_nth_info (tensors_info, index);
+    if (!_tensor_info) {
+      G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
+      return ML_ERROR_INVALID_PARAMETER;
+    }
     if (tensors_info->num_tensors <= index) {
       G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
       _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
@@ -660,8 +792,7 @@ ml_tensors_info_get_tensor_size (ml_tensors_info_h info,
     }
 
     *data_size =
-        _ml_tensor_info_get_size (&tensors_info->info[index],
-        tensors_info->is_extended);
+        _ml_tensor_info_get_size (_tensor_info, tensors_info->is_extended);
   }
 
   G_UNLOCK_UNLESS_NOLOCK (*tensors_info);
@@ -680,12 +811,22 @@ _ml_tensors_info_free (ml_tensors_info_s * info)
   if (!info)
     return;
 
-  for (i = 0; i < ML_TENSOR_SIZE_LIMIT; i++) {
+  for (i = 0; i < ML_TENSOR_SIZE_LIMIT_STATIC; i++) {
     if (info->info[i].name) {
       g_free (info->info[i].name);
     }
   }
 
+  if (info->extra) {
+    for (i = 0; i < ML_TENSOR_SIZE_EXTRA_LIMIT; i++) {
+      if (info->extra[i].name) {
+        g_free (info->extra[i].name);
+      }
+    }
+  }
+
+  g_free (info->extra);
+
   _ml_tensors_info_initialize (info);
 }
 
@@ -789,8 +930,9 @@ _ml_tensors_data_create_no_alloc (const ml_tensors_info_h info,
     G_LOCK_UNLESS_NOLOCK (*_info);
     _data->num_tensors = _info->num_tensors;
     for (i = 0; i < _data->num_tensors; i++) {
+      ml_tensor_info_s *_tensor_info = ml_tensors_info_get_nth_info (_info, i);
       _data->tensors[i].size =
-          _ml_tensor_info_get_size (&_info->info[i], _info->is_extended);
+          _ml_tensor_info_get_size (_tensor_info, _info->is_extended);
       _data->tensors[i].tensor = NULL;
     }
     G_UNLOCK_UNLESS_NOLOCK (*_info);
@@ -1055,7 +1197,8 @@ ml_tensors_info_clone (ml_tensors_info_h dest, const ml_tensors_info_h src)
   }
   if (!valid) {
     _ml_error_report
-        ("The parameter, src, is a ml_tensors_info_h handle without valid data. Every tensor-info of tensors-info should have a valid type and dimension information and the number of tensors should be between 1 and 16.");
+        ("The parameter, src, is a ml_tensors_info_h handle without valid data. Every tensor-info of tensors-info should have a valid type and dimension information and the number of tensors should be between 1 and %d.",
+        ML_TENSOR_SIZE_LIMIT);
     status = ML_ERROR_INVALID_PARAMETER;
     goto done;
   }
@@ -1066,12 +1209,25 @@ ml_tensors_info_clone (ml_tensors_info_h dest, const ml_tensors_info_h src)
   dest_info->is_extended = src_info->is_extended;
 
   for (i = 0; i < dest_info->num_tensors; i++) {
-    dest_info->info[i].name =
-        (src_info->info[i].name) ? g_strdup (src_info->info[i].name) : NULL;
-    dest_info->info[i].type = src_info->info[i].type;
+    ml_tensor_info_s *dest_tensor_info =
+        ml_tensors_info_get_nth_info (dest_info, i);
+    ml_tensor_info_s *src_tensor_info =
+        ml_tensors_info_get_nth_info (src_info, i);
+
+    if (!dest_tensor_info || !src_tensor_info) {
+      _ml_error_report
+          ("Cannot get the %u'th tensor info from src or dest. Maybe src or dest is not valid or its internal data is not consistent.",
+          i);
+      status = ML_ERROR_INVALID_PARAMETER;
+      goto done;
+    }
+
+    dest_tensor_info->name =
+        (src_tensor_info->name) ? g_strdup (src_tensor_info->name) : NULL;
+    dest_tensor_info->type = src_tensor_info->type;
 
     for (j = 0; j < ML_TENSOR_RANK_LIMIT; j++) {
-      dest_info->info[i].dimension[j] = src_info->info[i].dimension[j];
+      dest_tensor_info->dimension[j] = src_tensor_info->dimension[j];
     }
   }
 
index e18474e..c6df346 100644 (file)
@@ -57,8 +57,10 @@ gst_info_is_extended (const GstTensorsInfo * gst_info)
 {
   int i, j;
   for (i = 0; i < gst_info->num_tensors; i++) {
+    GstTensorInfo *_gst_tensor_info =
+        gst_tensors_info_get_nth_info ((GstTensorsInfo *) gst_info, i);
     for (j = ML_TENSOR_RANK_LIMIT_PREV; j < NNS_TENSOR_RANK_LIMIT; j++) {
-      if (gst_info->info[i].dimension[j] != 1)
+      if (_gst_tensor_info->dimension[j] != 1)
         return TRUE;
     }
   }
@@ -120,28 +122,45 @@ _ml_tensors_info_copy_from_gst (ml_tensors_info_s * ml_info,
 
   ml_info->num_tensors = gst_info->num_tensors;
   ml_info->is_extended = gst_info_is_extended (gst_info);
+  if (gst_info->extra) {
+    /* create ml_info_extra in ml_tensors_info_s */
+    _ml_tensors_info_create_extra (ml_info);
+  }
 
   for (i = 0; i < gst_info->num_tensors; i++) {
-    /* Copy name string */
-    if (gst_info->info[i].name) {
-      ml_info->info[i].name = g_strdup (gst_info->info[i].name);
+    GstTensorInfo *_gst_tensor_info =
+        gst_tensors_info_get_nth_info ((GstTensorsInfo *) gst_info, i);
+    ml_tensor_info_s *_ml_tensor_info =
+        ml_tensors_info_get_nth_info (ml_info, i);
+    if (!_gst_tensor_info) {
+      _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+          "The parameter, gst_info, is invalid. It should be a valid GstTensorsInfo instance. This is probably an internal bug of ML API.");
     }
 
-    ml_info->info[i].type =
-        convert_ml_tensor_type_from (gst_info->info[i].type);
+    if (!_ml_tensor_info) {
+      _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+          "The parameter, ml_info, is invalid. It should be a valid ml_tensors_info_s instance, usually created by ml_tensors_info_create(). This is probably an internal bug of ML API.");
+    }
+
+    if (_gst_tensor_info->name) {
+      _ml_tensor_info->name = g_strdup (_gst_tensor_info->name);
+    }
+
+    _ml_tensor_info->type =
+        convert_ml_tensor_type_from (_gst_tensor_info->type);
 
     /* Set dimension */
     for (j = 0; j < max_dim; j++) {
-      ml_info->info[i].dimension[j] = gst_info->info[i].dimension[j];
+      _ml_tensor_info->dimension[j] = _gst_tensor_info->dimension[j];
     }
 
     for (; j < ML_TENSOR_RANK_LIMIT; j++) {
-      ml_info->info[i].dimension[j] = 1;
+      _ml_tensor_info->dimension[j] = 1U;
     }
 
     if (!ml_info->is_extended) {
       for (j = ML_TENSOR_RANK_LIMIT_PREV; j < ML_TENSOR_RANK_LIMIT; j++) {
-        ml_info->info[i].dimension[j] = 1;
+        _ml_tensor_info->dimension[j] = 1U;
       }
     }
   }
@@ -174,25 +193,31 @@ _ml_tensors_info_copy_from_ml (GstTensorsInfo * gst_info,
   gst_info->num_tensors = ml_info->num_tensors;
 
   for (i = 0; i < ml_info->num_tensors; i++) {
+    ml_tensor_info_s *_ml_tensor_info =
+        ml_tensors_info_get_nth_info ((ml_tensors_info_s *) ml_info, i);
+    GstTensorInfo *_gst_tensor_info =
+        gst_tensors_info_get_nth_info (gst_info, i);
+
     /* Copy name string */
-    if (ml_info->info[i].name) {
-      gst_info->info[i].name = g_strdup (ml_info->info[i].name);
+    if (_ml_tensor_info->name) {
+      _gst_tensor_info->name = g_strdup (_ml_tensor_info->name);
     }
 
-    gst_info->info[i].type = convert_tensor_type_from (ml_info->info[i].type);
+    /* Copy type */
+    _gst_tensor_info->type = convert_tensor_type_from (_ml_tensor_info->type);
 
     /* Set dimension */
     for (j = 0; j < max_dim; j++) {
-      gst_info->info[i].dimension[j] = ml_info->info[i].dimension[j];
+      _gst_tensor_info->dimension[j] = _ml_tensor_info->dimension[j];
     }
 
     for (; j < NNS_TENSOR_RANK_LIMIT; j++) {
-      gst_info->info[i].dimension[j] = 1;
+      _gst_tensor_info->dimension[j] = 1;
     }
 
     if (!ml_info->is_extended) {
       for (j = ML_TENSOR_RANK_LIMIT_PREV; j < NNS_TENSOR_RANK_LIMIT; j++) {
-        gst_info->info[i].dimension[j] = 1;
+        _gst_tensor_info->dimension[j] = 1;
       }
     }
   }
index 5433a22..4b3fd3b 100644 (file)
@@ -375,7 +375,8 @@ cb_sink_event (GstElement * e, GstBuffer * b, gpointer user_data)
 
           for (i = 0; i < _info->num_tensors; i++) {
             size_t sz =
-                _ml_tensor_info_get_size (&_info->info[i], _info->is_extended);
+                _ml_tensor_info_get_size (ml_tensors_info_get_nth_info (_info,
+                    i), _info->is_extended);
 
             /* Not configured, yet. */
             if (sz == 0)
@@ -1557,8 +1558,10 @@ ml_pipeline_src_parse_tensors_info (ml_pipeline_element * elem)
     elem->is_flexible_tensor = flexible;
     if (!flexible) {
       for (i = 0; i < _info->num_tensors; i++) {
+        ml_tensor_info_s *_tensor_info =
+            ml_tensors_info_get_nth_info (_info, i);
         elem->size +=
-            _ml_tensor_info_get_size (&_info->info[i], _info->is_extended);
+            _ml_tensor_info_get_size (_tensor_info, _info->is_extended);
       }
     }
   } else {
@@ -1719,7 +1722,10 @@ ml_pipeline_src_input_data (ml_pipeline_src_h h, ml_tensors_data_h data,
     }
 
     for (i = 0; i < elem->tensors_info.num_tensors; i++) {
-      size_t sz = _ml_tensor_info_get_size (&elem->tensors_info.info[i],
+      ml_tensor_info_s *_tensor_info =
+          ml_tensors_info_get_nth_info (&elem->tensors_info, i);
+
+      size_t sz = _ml_tensor_info_get_size (_tensor_info,
           elem->tensors_info.is_extended);
 
       if (sz != _data->tensors[i].size) {
@@ -1738,6 +1744,8 @@ ml_pipeline_src_input_data (ml_pipeline_src_h h, ml_tensors_data_h data,
   _ml_tensors_info_copy_from_ml (&gst_info, _data->info);
 
   for (i = 0; i < _data->num_tensors; i++) {
+    GstTensorInfo *_gst_tensor_info =
+        gst_tensors_info_get_nth_info (&gst_info, i);
     mem_data = _data->tensors[i].tensor;
     mem_size = _data->tensors[i].size;
 
index bcbc6cf..f50e5bb 100644 (file)
@@ -295,8 +295,8 @@ __setup_in_out_tensors (ml_single * single_h)
     /** memory will be allocated by tensor_filter_single */
     in_tensors->tensors[i].tensor = NULL;
     in_tensors->tensors[i].size =
-        _ml_tensor_info_get_size (&single_h->in_info.info[i],
-        single_h->in_info.is_extended);
+        _ml_tensor_info_get_size (ml_tensors_info_get_nth_info
+        (&single_h->in_info, i), single_h->in_info.is_extended);
   }
 
   /** Setup output buffer */
@@ -308,8 +308,8 @@ __setup_in_out_tensors (ml_single * single_h)
     /** memory will be allocated by tensor_filter_single */
     out_tensors->tensors[i].tensor = NULL;
     out_tensors->tensors[i].size =
-        _ml_tensor_info_get_size (&single_h->out_info.info[i],
-        single_h->out_info.is_extended);
+        _ml_tensor_info_get_size (ml_tensors_info_get_nth_info
+        (&single_h->out_info, i), single_h->out_info.is_extended);
   }
 }
 
@@ -1353,7 +1353,7 @@ _ml_single_invoke_validate_data (ml_single_h single,
       _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
           "The size of %d-th %s tensor is not compatible with model. Given: %zu, Expected: %zu (type: %d).",
           i, (is_input) ? "input" : "output", _data->tensors[i].size, raw_size,
-          single_h->in_info.info[i].type);
+          ml_tensors_info_get_nth_info (&single_h->in_info, i)->type);
   }
 
   return ML_ERROR_NONE;
@@ -1820,7 +1820,7 @@ ml_single_set_property (ml_single_h single, const char *name, const char *value)
 
       for (i = 0; i < num; ++i) {
         rank[i] = gst_tensor_parse_dimension (str_dims[i],
-            gst_info.info[i].dimension);
+            gst_tensors_info_get_nth_info (&gst_info, i)->dimension);
       }
       g_strfreev (str_dims);
     }
@@ -1917,8 +1917,8 @@ ml_single_get_property (ml_single_h single, const char *name, char **value)
 
       for (i = 0; i < gst_info.num_tensors; ++i) {
         dim_str =
-            gst_tensor_get_rank_dimension_string (gst_info.info[i].dimension,
-            *(rank + i));
+            gst_tensor_get_rank_dimension_string (gst_tensors_info_get_nth_info
+            (&gst_info, i)->dimension, *(rank + i));
         g_string_append (dimensions, dim_str);
 
         if (i < gst_info.num_tensors - 1) {
index 327486c..21f9ee6 100644 (file)
@@ -160,7 +160,8 @@ typedef struct {
  */
 typedef struct {
   unsigned int num_tensors; /**< The number of tensors. */
-  ml_tensor_info_s info[ML_TENSOR_SIZE_LIMIT];  /**< The list of tensor info. */
+  ml_tensor_info_s info[ML_TENSOR_SIZE_LIMIT_STATIC];  /**< The list of tensor info. */
+  ml_tensor_info_s *extra; /**< The list of extra tensor info. */
   GMutex lock; /**< Lock for thread safety */
   int nolock; /**< Set non-zero to avoid using m (giving up thread safety) */
   bool is_extended; /**< True if tensors are extended */
@@ -293,6 +294,16 @@ typedef struct {
 size_t _ml_tensor_info_get_size (const ml_tensor_info_s *info, bool is_extended);
 
 /**
+ * @brief Allocates memory in given tensors_info for extra tensor infos.
+ */
+gboolean _ml_tensors_info_create_extra (ml_tensors_info_s * ml_info);
+
+/**
+ * @brief Initializes given tensor_info with default value.
+ */
+int _ml_tensor_info_initialize (ml_tensor_info_s * info);
+
+/**
  * @brief Initializes the tensors information with default value.
  * @since_tizen 5.5
  * @param[in] info The tensors info pointer to be initialized.
@@ -310,6 +321,11 @@ int _ml_tensors_info_initialize (ml_tensors_info_s *info);
 void _ml_tensors_info_free (ml_tensors_info_s *info);
 
 /**
+ * @brief Get the pointer of nth tensor info.
+ */
+ml_tensor_info_s * ml_tensors_info_get_nth_info (ml_tensors_info_s *info, guint nth);
+
+/**
  * @brief Creates a tensor data frame without allocating new buffer cloning the given tensors data.
  * @details If @a data_src is null, this returns error.
  * @param[in] data_src The handle of tensors data to be cloned.