/**
* @brief Macro to check the tensors info is valid.
- * @since_tizen 5.5
*/
-#define ml_tensors_info_is_valid(i,v) (ml_tensors_info_validate ((i), &(v)) == ML_ERROR_NONE && (v))
+#define ml_tensors_info_is_valid(i) ({bool v; (ml_tensors_info_validate ((i), &v) == ML_ERROR_NONE && v);})
+
+/**
+ * @brief Macro to compare the tensors info.
+ */
+#define ml_tensors_info_is_equal(i1,i2) ({bool e; (ml_tensors_info_compare ((i1), (i2), &e) == ML_ERROR_NONE && e);})
/**
* @brief Gets the byte size of the given tensor info.
int ml_tensors_info_initialize (ml_tensors_info_s *info);
/**
+ * @brief Compares the given tensors information.
+ * @details If the function returns an error, @a equal is not changed.
+ * @since_tizen 6.0
+ * @param[in] info1 The handle of tensors information to be compared.
+ * @param[in] info2 The handle of tensors information to be compared.
+ * @param[out] equal @c true if given tensors information is equal, @c false if if it's not equal.
+ * @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.
+ */
+int ml_tensors_info_compare (const ml_tensors_info_h info1, const ml_tensors_info_h info2, bool *equal);
+
+/**
* @brief Frees the tensors info pointer.
* @since_tizen 5.5
* @param[in] info The tensors info pointer to be freed.
/**
* @brief Creates a tensor data frame wihout buffer with the given tensors information.
+ * @details If @a info is null, this allocates data handle with empty tensor data.
* @param[in] info The handle of tensors information for the allocation.
* @param[out] data The handle of tensors data.
* @return @c 0 on success. Otherwise a negative error value.
}
/**
+ * @brief Compares the given tensor info.
+ */
+static gboolean
+ml_tensor_info_compare (const ml_tensor_info_s * i1, const ml_tensor_info_s * i2)
+{
+ guint i;
+
+ if (i1 == NULL || i2 == NULL)
+ return FALSE;
+
+ if (i1->type != i2->type)
+ return FALSE;
+
+ for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
+ if (i1->dimension[i] != i2->dimension[i])
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
* @brief Validates the given tensors info is valid.
*/
int
}
/**
+ * @brief Compares the given tensors information.
+ */
+int
+ml_tensors_info_compare (const ml_tensors_info_h info1,
+ const ml_tensors_info_h info2, bool * equal)
+{
+ ml_tensors_info_s *i1, *i2;
+ guint i;
+
+ check_feature_state ();
+
+ if (info1 == NULL || info2 == NULL || equal == NULL)
+ return ML_ERROR_INVALID_PARAMETER;
+
+ i1 = (ml_tensors_info_s *) info1;
+ i2 = (ml_tensors_info_s *) info2;
+
+ /* init false */
+ *equal = false;
+
+ if (i1->num_tensors != i2->num_tensors)
+ goto done;
+
+ for (i = 0; i < i1->num_tensors; i++) {
+ if (!ml_tensor_info_compare (&i1->info[i], &i2->info[i]))
+ goto done;
+ }
+
+ *equal = true;
+
+done:
+ return ML_ERROR_NONE;
+}
+
+/**
* @brief Sets the number of tensors with given handle of tensors information.
*/
int
ml_tensors_data_h * data)
{
ml_tensors_data_s *_data;
- ml_tensors_info_s *tensors_info;
+ ml_tensors_info_s *_info;
gint i;
check_feature_state ();
- if (!info || !data)
+ if (data == NULL)
return ML_ERROR_INVALID_PARAMETER;
- tensors_info = (ml_tensors_info_s *) info;
+ /* init null */
*data = NULL;
_data = g_new0 (ml_tensors_data_s, 1);
return ML_ERROR_OUT_OF_MEMORY;
}
- _data->num_tensors = tensors_info->num_tensors;
- for (i = 0; i < _data->num_tensors; i++) {
- _data->tensors[i].size = ml_tensor_info_get_size (&tensors_info->info[i]);
- _data->tensors[i].tensor = NULL;
+ _info = (ml_tensors_info_s *) info;
+ if (_info != NULL) {
+ _data->num_tensors = _info->num_tensors;
+ for (i = 0; i < _data->num_tensors; i++) {
+ _data->tensors[i].size = ml_tensor_info_get_size (&_info->info[i]);
+ _data->tensors[i].tensor = NULL;
+ }
}
*data = _data;
ml_tensors_data_s *_data = NULL;
gint i;
+ check_feature_state ();
+
+ if (info == NULL || data == NULL)
+ return ML_ERROR_INVALID_PARAMETER;
+
status = ml_tensors_data_create_no_alloc (info, (ml_tensors_data_h *) &_data);
if (status != ML_ERROR_NONE) {
EXPECT_EQ (status, ML_ERROR_NONE);
}
+/**
+ * @brief Test utility functions
+ */
+TEST (nnstreamer_capi_util, compare_info)
+{
+ ml_tensors_info_h info1, info2;
+ ml_tensor_dimension dim;
+ int status;
+
+ status = ml_tensors_info_create (&info1);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+
+ status = ml_tensors_info_create (&info2);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+
+ dim[0] = 3;
+ dim[1] = 4;
+ dim[2] = 4;
+ dim[3] = 1;
+
+ ml_tensors_info_set_count (info1, 1);
+ ml_tensors_info_set_tensor_type (info1, 0, ML_TENSOR_TYPE_UINT8);
+ ml_tensors_info_set_tensor_dimension (info1, 0, dim);
+
+ ml_tensors_info_set_count (info2, 1);
+ ml_tensors_info_set_tensor_type (info2, 0, ML_TENSOR_TYPE_UINT8);
+ ml_tensors_info_set_tensor_dimension (info2, 0, dim);
+
+ /* compare info */
+ EXPECT_TRUE (ml_tensors_info_is_equal (info1, info2));
+
+ /* change type */
+ ml_tensors_info_set_tensor_type (info2, 0, ML_TENSOR_TYPE_UINT16);
+ EXPECT_FALSE (ml_tensors_info_is_equal (info1, info2));
+
+ /* validate info */
+ EXPECT_TRUE (ml_tensors_info_is_valid (info2));
+
+ /* validate invalid dimension */
+ dim[3] = 0;
+ ml_tensors_info_set_tensor_dimension (info2, 0, dim);
+ EXPECT_FALSE (ml_tensors_info_is_valid (info2));
+
+ status = ml_tensors_info_destroy (info1);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+
+ status = ml_tensors_info_destroy (info2);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+}
+
#ifdef ENABLE_TENSORFLOW_LITE
/**
* @brief Test NNStreamer single shot (tensorflow-lite)