[Util] public function for tensor-data
authorJaeyun Jung <jy1210.jung@samsung.com>
Thu, 7 Mar 2024 09:21:37 +0000 (18:21 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Mon, 25 Mar 2024 03:08:47 +0000 (12:08 +0900)
Add new util functions,
1. clone tensor-data handle.
2. get tensors-info of tensor data frame.

This requires ACR for public release.

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
c/include/ml-api-common.h
c/src/ml-api-common.c
c/src/ml-api-internal.h
tests/capi/unittest_capi_inference.cc

index ae505c4..55e0d08 100644 (file)
@@ -397,6 +397,34 @@ int ml_tensors_data_get_tensor_data (ml_tensors_data_h data, unsigned int index,
 int ml_tensors_data_set_tensor_data (ml_tensors_data_h data, unsigned int index, const void *raw_data, const size_t data_size);
 
 /**
+ * @brief Copies the tensor data frame.
+ * @since_tizen 9.0
+ * @remarks The @a out should be released using ml_tensors_data_destroy().
+ * @param[in] in The handle of tensors data to be cloned.
+ * @param[out] out The handle of tensors data.
+ * @return @c 0 on success. Otherwise a negative error value.
+ * @retval #ML_ERROR_NONE Successful.
+ * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
+ * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
+ * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
+ */
+int ml_tensors_data_clone (const ml_tensors_data_h in, ml_tensors_data_h *out);
+
+/**
+ * @brief Gets the tensors information of given tensor data frame.
+ * @since_tizen 9.0
+ * @remarks The @a info should be released using ml_tensors_info_destroy().
+ * @param[in] data The handle of tensors data.
+ * @param[out] info The handle of tensors information.
+ * @return @c 0 on success. Otherwise a negative error value.
+ * @retval #ML_ERROR_NONE Successful.
+ * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
+ * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
+ * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
+ */
+int ml_tensors_data_get_info (const ml_tensors_data_h data, ml_tensors_info_h *info);
+
+/**
  * @brief Returns a human-readable string describing the last error.
  * @details This returns a human-readable, null-terminated string describing
  *         the most recent error that occurred from a call to one of the
index 4487f84..b24dbf4 100644 (file)
@@ -146,6 +146,32 @@ _ml_tensors_info_create_internal (ml_tensors_info_h * info, bool extended)
 }
 
 /**
+ * @brief Creates new tensors-info handle and copies tensors information.
+ */
+int
+_ml_tensors_info_create_from (const ml_tensors_info_h in,
+    ml_tensors_info_h * out)
+{
+  ml_tensors_info_s *_info;
+  int status;
+
+  if (!in || !out)
+    return ML_ERROR_INVALID_PARAMETER;
+
+  _info = (ml_tensors_info_s *) in;
+
+  if (_info->is_extended)
+    status = ml_tensors_info_create_extended (out);
+  else
+    status = ml_tensors_info_create (out);
+
+  if (status == ML_ERROR_NONE)
+    status = ml_tensors_info_clone (*out, in);
+
+  return status;
+}
+
+/**
  * @brief Allocates a tensors information handle with default value.
  */
 int
@@ -722,7 +748,7 @@ _ml_tensors_data_create_no_alloc (const ml_tensors_info_h info,
 {
   ml_tensors_data_s *_data;
   ml_tensors_info_s *_info;
-  gint i;
+  guint i;
 
   check_feature_state (ML_FEATURE);
 
@@ -742,11 +768,8 @@ _ml_tensors_data_create_no_alloc (const ml_tensors_info_h info,
 
   _info = (ml_tensors_info_s *) info;
   if (_info != NULL) {
-    if (_info->is_extended)
-      ml_tensors_info_create_extended (&_data->info);
-    else
-      ml_tensors_info_create (&_data->info);
-    ml_tensors_info_clone (_data->info, info);
+    /* Ignore error case when creating internal info handle (single-shot). */
+    _ml_tensors_info_create_from (info, &_data->info);
 
     G_LOCK_UNLESS_NOLOCK (*_info);
     _data->num_tensors = _info->info.num_tensors;
@@ -840,6 +863,41 @@ error:
 }
 
 /**
+ * @brief Gets the tensors information of given tensor data frame.
+ */
+int
+ml_tensors_data_get_info (const ml_tensors_data_h data,
+    ml_tensors_info_h * info)
+{
+  int status;
+  ml_tensors_data_s *_data;
+
+  check_feature_state (ML_FEATURE);
+
+  if (data == NULL) {
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, data, is NULL. It should be a valid ml_tensors_data_h handle, which is usually created by ml_tensors_data_create ().");
+  }
+
+  if (info == NULL) {
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, info, is NULL. It should be a valid pointer to a space that can hold a ml_tensors_info_h handle. E.g., ml_tensors_info_h info; ml_tensors_data_get_info (data, &info);.");
+  }
+
+  _data = (ml_tensors_data_s *) data;
+  G_LOCK_UNLESS_NOLOCK (*_data);
+
+  status = _ml_tensors_info_create_from (_data->info, info);
+  if (status != ML_ERROR_NONE) {
+    _ml_error_report_continue
+        ("Failed to get the tensor information from data handle.");
+  }
+
+  G_UNLOCK_UNLESS_NOLOCK (*_data);
+  return status;
+}
+
+/**
  * @brief Allocates a tensor data frame with the given tensors info. (more info in nnstreamer.h)
  */
 int
@@ -847,7 +905,7 @@ ml_tensors_data_create (const ml_tensors_info_h info, ml_tensors_data_h * data)
 {
   gint status = ML_ERROR_STREAMS_PIPE;
   ml_tensors_data_s *_data = NULL;
-  gint i;
+  guint i;
   bool valid;
 
   check_feature_state (ML_FEATURE);
index 90532eb..0854af3 100644 (file)
@@ -223,6 +223,11 @@ typedef struct {
 } ml_tensors_data_s;
 
 /**
+ * @brief Creates new tensors-info handle and copies tensors information.
+ */
+int _ml_tensors_info_create_from (const ml_tensors_info_h in, ml_tensors_info_h *out);
+
+/**
  * @brief Initializes the tensors information with default value.
  * @since_tizen 5.5
  * @param[in] info The tensors info pointer to be initialized.
@@ -252,20 +257,6 @@ void _ml_tensors_info_free (ml_tensors_info_s *info);
 int _ml_tensors_data_clone_no_alloc (const ml_tensors_data_s * data_src, ml_tensors_data_h * data);
 
 /**
- * @brief Copies the tensor data frame.
- * @since_tizen 8.0
- * @param[in] in The handle of tensors data to be cloned.
- * @param[out] out The handle of tensors data. The caller is responsible for freeing the allocated data with ml_tensors_data_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- * @todo Consider adding new API from tizen 8.0.
- */
-int ml_tensors_data_clone (const ml_tensors_data_h in, ml_tensors_data_h *out);
-
-/**
  * @brief Replaces string.
  * This function deallocates the input source string.
  * This is copied from nnstreamer/tensor_common.c by the nnstreamer maintainer.
index 8895925..64216a6 100644 (file)
@@ -4070,6 +4070,67 @@ TEST (nnstreamer_capi_util, data_clone_04_p)
 }
 
 /**
+ * @brief Test utility functions - get tensors-info from data handle.
+ */
+TEST (nnstreamer_capi_util, data_get_info_01_p)
+{
+  int status;
+  ml_tensors_info_h in_info, out_info;
+  ml_tensors_data_h data;
+  ml_tensor_dimension dim = { 5, 1, 1, 1 };
+
+  ml_tensors_info_create (&in_info);
+  ml_tensors_info_set_count (in_info, 1);
+  ml_tensors_info_set_tensor_type (in_info, 0, ML_TENSOR_TYPE_INT32);
+  ml_tensors_info_set_tensor_dimension (in_info, 0, dim);
+  ml_tensors_data_create (in_info, &data);
+
+  status = ml_tensors_data_get_info (data, &out_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  EXPECT_TRUE (ml_tensors_info_is_equal (in_info, out_info));
+
+  ml_tensors_info_destroy (in_info);
+  ml_tensors_info_destroy (out_info);
+  ml_tensors_data_destroy (data);
+}
+
+/**
+ * @brief Test utility functions - get tensors-info from data handle.
+ */
+TEST (nnstreamer_capi_util, data_get_info_02_n)
+{
+  int status;
+  ml_tensors_info_h out_info;
+
+  status = ml_tensors_data_get_info (nullptr, &out_info);
+  EXPECT_EQ (status, ML_ERROR_INVALID_PARAMETER);
+}
+
+/**
+ * @brief Test utility functions - get tensors-info from data handle.
+ */
+TEST (nnstreamer_capi_util, data_get_info_03_n)
+{
+  int status;
+  ml_tensors_info_h in_info;
+  ml_tensors_data_h data;
+  ml_tensor_dimension dim = { 5, 1, 1, 1 };
+
+  ml_tensors_info_create (&in_info);
+  ml_tensors_info_set_count (in_info, 1);
+  ml_tensors_info_set_tensor_type (in_info, 0, ML_TENSOR_TYPE_INT32);
+  ml_tensors_info_set_tensor_dimension (in_info, 0, dim);
+  ml_tensors_data_create (in_info, &data);
+
+  status = ml_tensors_data_get_info (data, nullptr);
+  EXPECT_EQ (status, ML_ERROR_INVALID_PARAMETER);
+
+  ml_tensors_info_destroy (in_info);
+  ml_tensors_data_destroy (data);
+}
+
+/**
  * @brief Test to replace string.
  */
 TEST (nnstreamer_capi_util, replaceStr01)