From: Yongjoo Ahn Date: Tue, 7 Mar 2023 11:18:40 +0000 (+0900) Subject: [service/model] Implement new APIS ml_service_model_* X-Git-Tag: accepted/tizen/unified/20230321.123159~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4dda98c617303a7a6881bc1ca2545010a3ac691d;p=platform%2Fcore%2Fapi%2Fmachine-learning.git [service/model] Implement new APIS ml_service_model_* - Add build dependency for the json-glib in .spec and meson.build - Implement new APIs using dbus glib apis. Signed-off-by: Yongjoo Ahn --- diff --git a/c/src/meson.build b/c/src/meson.build index ff5e3fe..5c791ed 100644 --- a/c/src/meson.build +++ b/c/src/meson.build @@ -102,7 +102,7 @@ nns_capi_dep = declare_dependency(link_with: nns_capi_lib, if get_option('enable-ml-service') nns_capi_service_shared_lib = shared_library ('capi-ml-service', nns_capi_service_srcs, - dependencies: [nns_capi_dep, ai_service_daemon_deps], + dependencies: [nns_capi_dep, ai_service_daemon_deps, json_glib_dep], include_directories: nns_capi_include, install: true, install_dir: api_install_libdir, @@ -111,7 +111,7 @@ if get_option('enable-ml-service') nns_capi_service_static_lib = static_library ('capi-ml-service', nns_capi_service_srcs, - dependencies: [nns_capi_dep, ai_service_daemon_deps], + dependencies: [nns_capi_dep, ai_service_daemon_deps, json_glib_dep], include_directories: nns_capi_include, install: true, install_dir: api_install_libdir, diff --git a/c/src/ml-api-service-agent-client.c b/c/src/ml-api-service-agent-client.c index 2c71f75..f7ceeaf 100644 --- a/c/src/ml-api-service-agent-client.c +++ b/c/src/ml-api-service-agent-client.c @@ -11,6 +11,7 @@ */ #include +#include #include "ml-api-internal.h" #include "ml-api-service.h" @@ -336,13 +337,14 @@ ml_service_get_pipeline_state (ml_service_h h, ml_pipeline_state_e * state) } /** - * @brief TBU + * @brief Registers new information of a neural network model. */ int ml_service_model_register (const char *name, const char *path, const bool activate, const char *description, unsigned int *version) { int ret = ML_ERROR_NONE; + MachinelearningServiceModel *mlsm; GError *err = NULL; gboolean result; @@ -383,8 +385,9 @@ ml_service_model_register (const char *name, const char *path, "Failed to get dbus proxy."); } - result = machinelearning_service_model_call_register_sync (mlsm, - name, path, version, &ret, NULL, &err); + result = + machinelearning_service_model_call_register_sync (mlsm, name, path, + activate, description ? description : "", version, &ret, NULL, &err); g_object_unref (mlsm); @@ -397,3 +400,463 @@ ml_service_model_register (const char *name, const char *path, return ret; } + +/** + * @brief Updates the description of neural network model with given @a name and @a version. + */ +int +ml_service_model_update_description (const char *name, + const unsigned int version, const char *description) +{ + int ret = ML_ERROR_NONE; + + MachinelearningServiceModel *mlsm; + GError *err = NULL; + gboolean result; + + check_feature_state (ML_FEATURE_SERVICE); + + if (!name) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'name' is NULL. It should be a valid string"); + + if (version == 0U) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'version' is 0. It should be a valid unsigned int"); + + if (!description) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'description' is NULL. It should be a valid string"); + + mlsm = _get_mlsm_proxy_new_for_bus_sync (); + if (!mlsm) { + _ml_error_report_return (ML_ERROR_NOT_SUPPORTED, + "Failed to get dbus proxy."); + } + + result = machinelearning_service_model_call_update_description_sync (mlsm, + name, version, description, &ret, NULL, &err); + + g_object_unref (mlsm); + + if (!result) { + _ml_error_report ("Failed to invoke the method update_description (%s).", + err ? err->message : "Unknown error"); + ret = ML_ERROR_IO_ERROR; + } + + g_clear_error (&err); + + return ret; +} + +/** + * @brief Activates a neural network model with given @a name and @a version. + */ +int +ml_service_model_activate (const char *name, const unsigned int version) +{ + int ret = ML_ERROR_NONE; + + MachinelearningServiceModel *mlsm; + GError *err = NULL; + gboolean result; + + check_feature_state (ML_FEATURE_SERVICE); + + if (!name) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'name' is NULL. It should be a valid string"); + + if (version == 0U) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'version' is 0. It should be a valid unsigned int"); + + mlsm = _get_mlsm_proxy_new_for_bus_sync (); + if (!mlsm) { + _ml_error_report_return (ML_ERROR_NOT_SUPPORTED, + "Failed to get dbus proxy."); + } + + result = machinelearning_service_model_call_activate_sync (mlsm, + name, version, &ret, NULL, &err); + + g_object_unref (mlsm); + + if (!result) { + _ml_error_report ("Failed to invoke the method activate (%s).", + err ? err->message : "Unknown error"); + ret = ML_ERROR_IO_ERROR; + } + + g_clear_error (&err); + + return ret; +} + +/** + * @brief Gets the information of neural network model with given @a name and @a version. + */ +int +ml_service_model_get (const char *name, const unsigned int version, + ml_option_h * info) +{ + int ret = ML_ERROR_NONE; + + ml_option_h _info = NULL; + MachinelearningServiceModel *mlsm; + GError *err = NULL; + gboolean result; + gchar *description; + + JsonParser *parser; + JsonObjectIter iter; + JsonNode *root_node; + JsonNode *member_node; + const gchar *member_name; + JsonObject *j_object; + + check_feature_state (ML_FEATURE_SERVICE); + + if (!name) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'name' is NULL. It should be a valid string"); + + if (!info) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'info' is NULL. It should be a valid pointer to ml_info_h"); + + mlsm = _get_mlsm_proxy_new_for_bus_sync (); + if (!mlsm) { + _ml_error_report_return (ML_ERROR_NOT_SUPPORTED, + "Failed to get dbus proxy."); + } + + result = machinelearning_service_model_call_get_sync (mlsm, + name, version, &description, &ret, NULL, &err); + + g_object_unref (mlsm); + + if (!result) { + _ml_error_report ("Failed to invoke the method get_activated (%s).", + err ? err->message : "Unknown error"); + ret = ML_ERROR_IO_ERROR; + g_clear_error (&err); + } + + if (ML_ERROR_NONE != ret) { + g_free (description); + return ret; + } + + ret = ml_option_create (&_info); + if (ML_ERROR_NONE != ret) { + g_free (description); + return ret; + } + + /* fill ml_info */ + parser = json_parser_new (); + if (!parser) { + g_free (description); + _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY, + "Failed to allocate memory for JsonParser. Out of memory?"); + } + + if (!json_parser_load_from_data (parser, description, -1, &err)) { + g_free (description); + g_error_free (err); + g_object_unref (parser); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to parse the json string. %s", err->message); + } + + root_node = json_parser_get_root (parser); + if (!root_node) { + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to get the root node of json string."); + } + + j_object = json_node_get_object (root_node); + json_object_iter_init_ordered (&iter, j_object); + while (json_object_iter_next_ordered (&iter, &member_name, &member_node)) { + const gchar *value = json_object_get_string_member (j_object, member_name); + ml_option_set (_info, member_name, g_strdup (value), g_free); + } + + g_object_unref (parser); + g_free (description); + + *info = _info; + + return ret; +} + +/** + * @brief Gets the information of activated neural network model with given @a name. + */ +int +ml_service_model_get_activated (const char *name, ml_option_h * info) +{ + int ret = ML_ERROR_NONE; + + ml_option_h _info = NULL; + MachinelearningServiceModel *mlsm; + GError *err = NULL; + gboolean result; + gchar *description; + + JsonParser *parser; + JsonObjectIter iter; + JsonNode *root_node; + JsonNode *member_node; + const gchar *member_name; + JsonObject *j_object; + + check_feature_state (ML_FEATURE_SERVICE); + + if (!name) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'name' is NULL. It should be a valid string"); + + if (!info) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'info' is NULL. It should be a valid pointer to ml_info_h"); + + mlsm = _get_mlsm_proxy_new_for_bus_sync (); + if (!mlsm) { + _ml_error_report_return (ML_ERROR_NOT_SUPPORTED, + "Failed to get dbus proxy."); + } + + result = machinelearning_service_model_call_get_activated_sync (mlsm, + name, &description, &ret, NULL, &err); + + g_object_unref (mlsm); + + if (!result) { + _ml_error_report ("Failed to invoke the method get_activated (%s).", + err ? err->message : "Unknown error"); + ret = ML_ERROR_IO_ERROR; + g_clear_error (&err); + } + + if (ML_ERROR_NONE != ret) { + g_free (description); + return ret; + } + + ret = ml_option_create (&_info); + if (ML_ERROR_NONE != ret) { + g_free (description); + return ret; + } + + /* fill ml_info */ + parser = json_parser_new (); + if (!parser) { + _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY, + "Failed to allocate memory for JsonParser. Out of memory?"); + } + + if (!json_parser_load_from_data (parser, description, -1, &err)) { + g_error_free (err); + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to parse the json string. %s", err->message); + } + + root_node = json_parser_get_root (parser); + if (!root_node) { + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to get the root node of json string."); + } + + j_object = json_node_get_object (root_node); + json_object_iter_init_ordered (&iter, j_object); + while (json_object_iter_next_ordered (&iter, &member_name, &member_node)) { + const gchar *value = json_object_get_string_member (j_object, member_name); + ml_option_set (_info, member_name, g_strdup (value), g_free); + } + + g_object_unref (parser); + g_free (description); + + *info = _info; + + return ret; +} + +/** + * @brief Gets the list of neural network model with given @a name. + */ +int +ml_service_model_get_all (const char *name, ml_option_h * info_list[], + unsigned int *num) +{ + int ret = ML_ERROR_NONE; + + ml_option_h *_info_list = NULL; + MachinelearningServiceModel *mlsm; + GError *err = NULL; + gboolean result; + gchar *description = NULL; + guint i; + + JsonParser *parser; + JsonArray *array; + + check_feature_state (ML_FEATURE_SERVICE); + + if (!name) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'name' is NULL. It should be a valid string"); + + if (!info_list) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'info' is NULL. It should be a valid pointer to array of ml_info_h"); + + if (!num) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'num' is NULL. It should be a valid pointer to unsigned int"); + + mlsm = _get_mlsm_proxy_new_for_bus_sync (); + if (!mlsm) { + _ml_error_report_return (ML_ERROR_NOT_SUPPORTED, + "Failed to get dbus proxy."); + } + + result = machinelearning_service_model_call_get_all_sync (mlsm, + name, &description, &ret, NULL, &err); + + g_object_unref (mlsm); + + if (!result) { + _ml_error_report ("Failed to invoke the method get_activated (%s).", + err ? err->message : "Unknown error"); + ret = ML_ERROR_IO_ERROR; + g_clear_error (&err); + } + + if (ML_ERROR_NONE != ret) { + g_free (description); + return ret; + } + + if (!description) { + *num = 0; + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "There is no model with name %s", name); + } + + parser = json_parser_new (); + if (!parser) { + g_free (description); + _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY, + "Failed to allocate memory for JsonParser. Out of memory?"); + } + + if (!json_parser_load_from_data (parser, description, -1, &err)) { + g_error_free (err); + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to parse the json string. %s", err->message); + } + + array = json_node_get_array (json_parser_get_root (parser)); + if (!array) { + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to get array from json string."); + } + + *num = json_array_get_length (array); + + if (*num == 0U) { + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "Failed to get array from json string."); + } + + _info_list = g_new0 (ml_option_h, *num); + if (!_info_list) { + g_free (description); + _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY, + "Failed to allocate memory for list of ml_info_h. Out of memory?"); + } + + for (i = 0; i < *num; i++) { + JsonObjectIter iter; + const gchar *member_name; + JsonNode *member_node; + JsonObject *object; + + if (ml_option_create (&_info_list[i]) != ML_ERROR_NONE) { + g_object_unref (parser); + g_free (description); + _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY, + "Failed to allocate memory for ml_option_h. Out of memory?"); + } + + object = json_array_get_object_element (array, i); + json_object_iter_init_ordered (&iter, object); + while (json_object_iter_next_ordered (&iter, &member_name, &member_node)) { + const gchar *value = json_object_get_string_member (object, member_name); + ml_option_set (_info_list[i], member_name, g_strdup (value), g_free); + } + } + + g_object_unref (parser); + g_free (description); + + *info_list = _info_list; + + return ret; +} + +/** + * @brief Deletes a model information with given @a name and @a version from machine learning service. + */ +int +ml_service_model_delete (const char *name, const unsigned int version) +{ + int ret = ML_ERROR_NONE; + MachinelearningServiceModel *mlsm; + GError *err = NULL; + gboolean result; + + check_feature_state (ML_FEATURE_SERVICE); + + if (!name) + _ml_error_report_return (ML_ERROR_INVALID_PARAMETER, + "The parameter, 'name' is NULL. It should be a valid string"); + + mlsm = _get_mlsm_proxy_new_for_bus_sync (); + if (!mlsm) { + _ml_error_report_return (ML_ERROR_NOT_SUPPORTED, + "Failed to get dbus proxy."); + } + + result = machinelearning_service_model_call_delete_sync (mlsm, + name, version, &ret, NULL, &err); + + g_object_unref (mlsm); + + if (!result) { + _ml_error_report ("Failed to invoke the method delete (%s).", + err ? err->message : "Unknown error"); + ret = ML_ERROR_IO_ERROR; + } + + g_clear_error (&err); + + return ret; +} diff --git a/meson.build b/meson.build index 1b81181..c7824db 100644 --- a/meson.build +++ b/meson.build @@ -34,6 +34,7 @@ nnstreamer_dep = dependency('nnstreamer') if get_option('enable-ml-service') libsystemd_dep = dependency('libsystemd') sqlite_dep = dependency('sqlite3') + json_glib_dep = dependency('json-glib-1.0') if get_option('enable-tizen') appfw_package_manager_dep = dependency('capi-appfw-package-manager') diff --git a/packaging/machine-learning-api.spec b/packaging/machine-learning-api.spec index 8f5a57c..3926f36 100644 --- a/packaging/machine-learning-api.spec +++ b/packaging/machine-learning-api.spec @@ -156,6 +156,7 @@ BuildConflicts: libarmcl-release %if 0%{?enable_ml_service} BuildRequires: pkgconfig(libsystemd) BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(json-glib-1.0) BuildRequires: dbus BuildRequires: pkgconfig(capi-appfw-package-manager) %endif