LCOV - code coverage report
Current view: top level - capi-machine-learning-inference-1.8.5/c/src - ml-api-service.c (source / functions) Coverage Total Hit
Test: ML API 1.8.5-0 platform/core/api/machine-learning#631dc84d7897cf891d276061d07fd0136e5e4915 Lines: 0.0 % 343 0
Test Date: 2024-05-23 14:26:16 Functions: 0.0 % 18 0

            Line data    Source code
       1              : /* SPDX-License-Identifier: Apache-2.0 */
       2              : /**
       3              :  * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
       4              :  *
       5              :  * @file ml-api-service.c
       6              :  * @date 31 Aug 2022
       7              :  * @brief Some implementation of NNStreamer/Service C-API
       8              :  * @see https://github.com/nnstreamer/nnstreamer
       9              :  * @author Yongjoo Ahn <yongjoo1.ahn@samsung.com>
      10              :  * @bug No known bugs except for NYI items
      11              :  */
      12              : 
      13              : #include <nnstreamer_plugin_api_util.h>
      14              : 
      15              : #include "ml-api-service.h"
      16              : #include "ml-api-service-extension.h"
      17              : #include "ml-api-service-offloading.h"
      18              : 
      19              : #define ML_SERVICE_MAGIC 0xfeeedeed
      20              : #define ML_SERVICE_MAGIC_DEAD 0xdeaddead
      21              : 
      22              : /**
      23              :  * @brief Internal function to validate ml-service handle.
      24              :  */
      25              : gboolean
      26            0 : _ml_service_handle_is_valid (ml_service_s * mls)
      27              : {
      28            0 :   if (!mls)
      29            0 :     return FALSE;
      30              : 
      31            0 :   if (mls->magic != ML_SERVICE_MAGIC)
      32            0 :     return FALSE;
      33              : 
      34            0 :   switch (mls->type) {
      35            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
      36              :     case ML_SERVICE_TYPE_CLIENT_QUERY:
      37              :     case ML_SERVICE_TYPE_OFFLOADING:
      38              :     case ML_SERVICE_TYPE_EXTENSION:
      39            0 :       if (mls->priv == NULL)
      40            0 :         return FALSE;
      41            0 :       break;
      42            0 :     default:
      43              :       /* Invalid handle type. */
      44            0 :       return FALSE;
      45              :   }
      46              : 
      47            0 :   return TRUE;
      48              : }
      49              : 
      50              : /**
      51              :  * @brief Internal function to set information.
      52              :  */
      53              : static int
      54            0 : _ml_service_set_information_internal (ml_service_s * mls, const char *name,
      55              :     const char *value)
      56              : {
      57            0 :   int status = ML_ERROR_NONE;
      58              : 
      59              :   /* Prevent empty string case. */
      60            0 :   if (!STR_IS_VALID (name) || !STR_IS_VALID (value))
      61            0 :     return ML_ERROR_INVALID_PARAMETER;
      62              : 
      63            0 :   status = ml_option_set (mls->information, name, g_strdup (value), g_free);
      64            0 :   if (status != ML_ERROR_NONE)
      65            0 :     return status;
      66              : 
      67            0 :   switch (mls->type) {
      68            0 :     case ML_SERVICE_TYPE_EXTENSION:
      69            0 :       status = ml_service_extension_set_information (mls, name, value);
      70            0 :       break;
      71            0 :     case ML_SERVICE_TYPE_OFFLOADING:
      72            0 :       status = ml_service_offloading_set_information (mls, name, value);
      73            0 :       break;
      74            0 :     default:
      75            0 :       break;
      76              :   }
      77              : 
      78            0 :   return status;
      79              : }
      80              : 
      81              : /**
      82              :  * @brief Internal function to create new ml-service handle.
      83              :  */
      84              : ml_service_s *
      85            0 : _ml_service_create_internal (ml_service_type_e ml_service_type)
      86              : {
      87              :   ml_service_s *mls;
      88              :   int status;
      89              : 
      90            0 :   mls = g_try_new0 (ml_service_s, 1);
      91            0 :   if (mls) {
      92            0 :     status = ml_option_create (&mls->information);
      93            0 :     if (status != ML_ERROR_NONE) {
      94            0 :       g_free (mls);
      95            0 :       _ml_error_report_return (NULL,
      96              :           "Failed to create ml-option handle in ml-service.");
      97              :     }
      98              : 
      99            0 :     mls->magic = ML_SERVICE_MAGIC;
     100            0 :     mls->type = ml_service_type;
     101            0 :     g_mutex_init (&mls->lock);
     102            0 :     g_cond_init (&mls->cond);
     103              :   }
     104              : 
     105            0 :   return mls;
     106              : }
     107              : 
     108              : /**
     109              :  * @brief Internal function to release ml-service handle.
     110              :  */
     111              : int
     112            0 : _ml_service_destroy_internal (ml_service_s * mls)
     113              : {
     114              :   ml_service_event_cb_info_s old_cb;
     115            0 :   int status = ML_ERROR_NONE;
     116              : 
     117            0 :   if (!mls) {
     118              :     /* Internal error? */
     119            0 :     return ML_ERROR_INVALID_PARAMETER;
     120              :   }
     121              : 
     122              :   /* Clear callback before closing internal handles. */
     123            0 :   g_mutex_lock (&mls->lock);
     124            0 :   old_cb = mls->cb_info;
     125            0 :   memset (&mls->cb_info, 0, sizeof (ml_service_event_cb_info_s));
     126            0 :   g_mutex_unlock (&mls->lock);
     127              : 
     128            0 :   switch (mls->type) {
     129            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
     130            0 :       status = ml_service_pipeline_release_internal (mls);
     131            0 :       break;
     132            0 :     case ML_SERVICE_TYPE_CLIENT_QUERY:
     133            0 :       status = ml_service_query_release_internal (mls);
     134            0 :       break;
     135            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     136            0 :       status = ml_service_offloading_release_internal (mls);
     137            0 :       break;
     138            0 :     case ML_SERVICE_TYPE_EXTENSION:
     139            0 :       status = ml_service_extension_destroy (mls);
     140            0 :       break;
     141            0 :     default:
     142            0 :       _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     143              :           "Invalid type of ml_service_h.");
     144              :   }
     145              : 
     146            0 :   if (status == ML_ERROR_NONE) {
     147            0 :     mls->magic = ML_SERVICE_MAGIC_DEAD;
     148            0 :     ml_option_destroy (mls->information);
     149              : 
     150            0 :     g_cond_clear (&mls->cond);
     151            0 :     g_mutex_clear (&mls->lock);
     152            0 :     g_free (mls);
     153              :   } else {
     154            0 :     _ml_error_report ("Failed to release ml-service handle, internal error?");
     155              : 
     156            0 :     g_mutex_lock (&mls->lock);
     157            0 :     mls->cb_info = old_cb;
     158            0 :     g_mutex_unlock (&mls->lock);
     159              :   }
     160              : 
     161            0 :   return status;
     162              : }
     163              : 
     164              : /**
     165              :  * @brief Internal function to get ml-service event callback.
     166              :  */
     167              : void
     168            0 : _ml_service_get_event_cb_info (ml_service_s * mls,
     169              :     ml_service_event_cb_info_s * cb_info)
     170              : {
     171            0 :   if (!mls || !cb_info)
     172            0 :     return;
     173              : 
     174            0 :   g_mutex_lock (&mls->lock);
     175            0 :   *cb_info = mls->cb_info;
     176            0 :   g_mutex_unlock (&mls->lock);
     177              : }
     178              : 
     179              : /**
     180              :  * @brief Internal function to parse string value from json.
     181              :  */
     182              : int
     183            0 : _ml_service_conf_parse_string (JsonNode * str_node, const gchar * delimiter,
     184              :     gchar ** str)
     185              : {
     186              :   guint i, n;
     187              : 
     188            0 :   if (!str_node || !delimiter || !str)
     189            0 :     return ML_ERROR_INVALID_PARAMETER;
     190              : 
     191            0 :   *str = NULL;
     192              : 
     193            0 :   if (JSON_NODE_HOLDS_ARRAY (str_node)) {
     194            0 :     JsonArray *array = json_node_get_array (str_node);
     195            0 :     GString *val = g_string_new (NULL);
     196              : 
     197            0 :     n = (array) ? json_array_get_length (array) : 0U;
     198            0 :     for (i = 0; i < n; i++) {
     199            0 :       const gchar *p = json_array_get_string_element (array, i);
     200              : 
     201              :       g_string_append (val, p);
     202            0 :       if (i < n - 1)
     203              :         g_string_append (val, delimiter);
     204              :     }
     205              : 
     206            0 :     *str = g_string_free (val, FALSE);
     207              :   } else {
     208            0 :     *str = g_strdup (json_node_get_string (str_node));
     209              :   }
     210              : 
     211            0 :   return (*str != NULL) ? ML_ERROR_NONE : ML_ERROR_INVALID_PARAMETER;
     212              : }
     213              : 
     214              : /**
     215              :  * @brief Internal function to parse tensors-info from json.
     216              :  */
     217              : int
     218            0 : _ml_service_conf_parse_tensors_info (JsonNode * info_node,
     219              :     ml_tensors_info_h * info_h)
     220              : {
     221            0 :   JsonArray *array = NULL;
     222              :   JsonObject *object;
     223              :   GstTensorsInfo info;
     224              :   GstTensorInfo *_info;
     225              :   const gchar *_str;
     226              :   guint i;
     227              :   int status;
     228              : 
     229            0 :   if (!info_node || !info_h)
     230            0 :     return ML_ERROR_INVALID_PARAMETER;
     231              : 
     232            0 :   gst_tensors_info_init (&info);
     233              : 
     234            0 :   info.num_tensors = 1;
     235            0 :   if (JSON_NODE_HOLDS_ARRAY (info_node)) {
     236            0 :     array = json_node_get_array (info_node);
     237            0 :     info.num_tensors = json_array_get_length (array);
     238              :   }
     239              : 
     240            0 :   for (i = 0; i < info.num_tensors; i++) {
     241            0 :     _info = gst_tensors_info_get_nth_info (&info, i);
     242              : 
     243            0 :     if (array)
     244            0 :       object = json_array_get_object_element (array, i);
     245              :     else
     246            0 :       object = json_node_get_object (info_node);
     247              : 
     248            0 :     if (json_object_has_member (object, "type")) {
     249            0 :       _str = json_object_get_string_member (object, "type");
     250              : 
     251            0 :       if (STR_IS_VALID (_str))
     252            0 :         _info->type = gst_tensor_get_type (_str);
     253              :     }
     254              : 
     255            0 :     if (json_object_has_member (object, "dimension")) {
     256            0 :       _str = json_object_get_string_member (object, "dimension");
     257              : 
     258            0 :       if (STR_IS_VALID (_str))
     259            0 :         gst_tensor_parse_dimension (_str, _info->dimension);
     260              :     }
     261              : 
     262            0 :     if (json_object_has_member (object, "name")) {
     263            0 :       _str = json_object_get_string_member (object, "name");
     264              : 
     265            0 :       if (STR_IS_VALID (_str))
     266            0 :         _info->name = g_strdup (_str);
     267              :     }
     268              :   }
     269              : 
     270            0 :   if (gst_tensors_info_validate (&info))
     271            0 :     status = _ml_tensors_info_create_from_gst (info_h, &info);
     272              :   else
     273            0 :     status = ML_ERROR_INVALID_PARAMETER;
     274              : 
     275            0 :   gst_tensors_info_free (&info);
     276            0 :   return status;
     277              : }
     278              : 
     279              : /**
     280              :  * @brief Internal function to get ml-service type.
     281              :  */
     282              : static ml_service_type_e
     283            0 : _ml_service_get_type (JsonObject * object)
     284              : {
     285            0 :   ml_service_type_e type = ML_SERVICE_TYPE_UNKNOWN;
     286              : 
     287              :   /** @todo add more services such as training offloading, offloading service */
     288            0 :   if (json_object_has_member (object, "single") ||
     289            0 :       json_object_has_member (object, "pipeline")) {
     290            0 :     type = ML_SERVICE_TYPE_EXTENSION;
     291            0 :   } else if (json_object_has_member (object, "offloading")) {
     292            0 :     type = ML_SERVICE_TYPE_OFFLOADING;
     293              :   }
     294              : 
     295            0 :   return type;
     296              : }
     297              : 
     298              : /**
     299              :  * @brief Creates a handle for machine learning service with configuration.
     300              :  */
     301              : int
     302            0 : ml_service_new (const char *config, ml_service_h * handle)
     303              : {
     304              :   ml_service_s *mls;
     305            0 :   ml_service_type_e service_type = ML_SERVICE_TYPE_UNKNOWN;
     306            0 :   g_autofree gchar *json_string = NULL;
     307            0 :   g_autoptr (JsonParser) parser = NULL;
     308            0 :   g_autoptr (GError) err = NULL;
     309              :   JsonNode *root;
     310              :   JsonObject *object;
     311              :   int status;
     312              : 
     313            0 :   check_feature_state (ML_FEATURE_SERVICE);
     314              : 
     315            0 :   if (!handle) {
     316            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     317              :         "The parameter, 'handle' (ml_service_h), is NULL. It should be a valid pointer to create new instance.");
     318              :   }
     319              : 
     320              :   /* Init null. */
     321            0 :   *handle = NULL;
     322              : 
     323            0 :   if (!STR_IS_VALID (config) ||
     324            0 :       !g_file_test (config, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) {
     325            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     326              :         "The parameter, config, is invalid. It should be a valid path.");
     327              :   }
     328              : 
     329            0 :   if (!g_file_get_contents (config, &json_string, NULL, NULL)) {
     330            0 :     _ml_error_report_return (ML_ERROR_IO_ERROR,
     331              :         "Failed to read configuration file '%s'.", config);
     332              :   }
     333              : 
     334            0 :   parser = json_parser_new ();
     335            0 :   if (!parser) {
     336            0 :     _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
     337              :         "Failed to parse configuration file, cannot allocate memory for JsonParser. Out of memory?");
     338              :   }
     339              : 
     340            0 :   if (!json_parser_load_from_data (parser, json_string, -1, &err)) {
     341            0 :     _ml_error_report_return (ML_ERROR_IO_ERROR,
     342              :         "Failed to parse configuration file, cannot load json string (%s).",
     343              :         err ? err->message : "Unknown error");
     344              :   }
     345              : 
     346            0 :   root = json_parser_get_root (parser);
     347            0 :   if (!root) {
     348            0 :     _ml_error_report_return (ML_ERROR_IO_ERROR,
     349              :         "Failed to parse configuration file, cannot get the top node from json string.");
     350              :   }
     351              : 
     352            0 :   object = json_node_get_object (root);
     353              : 
     354            0 :   service_type = _ml_service_get_type (object);
     355            0 :   if (ML_SERVICE_TYPE_UNKNOWN == service_type) {
     356            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     357              :         "Failed to parse configuration file, cannot get the valid type from configuration.");
     358              :   }
     359              : 
     360              :   /* Parse each service type. */
     361            0 :   mls = _ml_service_create_internal (service_type);
     362            0 :   if (mls == NULL) {
     363            0 :     _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
     364              :         "Failed to allocate memory for the ml-service handle. Out of memory?");
     365              :   }
     366              : 
     367            0 :   switch (service_type) {
     368            0 :     case ML_SERVICE_TYPE_EXTENSION:
     369            0 :       status = ml_service_extension_create (mls, object);
     370            0 :       break;
     371            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     372            0 :       status = ml_service_offloading_create (mls, object);
     373            0 :       break;
     374            0 :     default:
     375              :       /* Invalid handle type. */
     376            0 :       status = ML_ERROR_NOT_SUPPORTED;
     377            0 :       break;
     378              :   }
     379              : 
     380            0 :   if (status != ML_ERROR_NONE)
     381            0 :     goto error;
     382              : 
     383              :   /* Parse information. */
     384            0 :   if (json_object_has_member (object, "information")) {
     385            0 :     JsonObject *info = json_object_get_object_member (object, "information");
     386            0 :     g_autoptr (GList) members = json_object_get_members (info);
     387              :     GList *iter;
     388              : 
     389            0 :     for (iter = members; iter; iter = g_list_next (iter)) {
     390            0 :       const gchar *name = iter->data;
     391            0 :       const gchar *value = json_object_get_string_member (info, name);
     392              : 
     393            0 :       status = _ml_service_set_information_internal (mls, name, value);
     394            0 :       if (status != ML_ERROR_NONE)
     395            0 :         goto error;
     396              :     }
     397              :   }
     398              : 
     399            0 : error:
     400            0 :   if (status == ML_ERROR_NONE) {
     401            0 :     *handle = mls;
     402              :   } else {
     403            0 :     _ml_error_report ("Failed to open the ml-service configuration.");
     404            0 :     _ml_service_destroy_internal (mls);
     405              :   }
     406              : 
     407            0 :   return status;
     408              : }
     409              : 
     410              : /**
     411              :  * @brief Sets the callbacks which will be invoked when a new event occurs from ml-service.
     412              :  */
     413              : int
     414            0 : ml_service_set_event_cb (ml_service_h handle, ml_service_event_cb cb,
     415              :     void *user_data)
     416              : {
     417            0 :   ml_service_s *mls = (ml_service_s *) handle;
     418              : 
     419            0 :   check_feature_state (ML_FEATURE_SERVICE);
     420              : 
     421            0 :   if (!_ml_service_handle_is_valid (mls)) {
     422            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     423              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     424              :   }
     425              : 
     426            0 :   g_mutex_lock (&mls->lock);
     427              : 
     428            0 :   mls->cb_info.cb = cb;
     429            0 :   mls->cb_info.pdata = user_data;
     430              : 
     431            0 :   g_mutex_unlock (&mls->lock);
     432              : 
     433            0 :   return ML_ERROR_NONE;
     434              : }
     435              : 
     436              : /**
     437              :  * @brief Starts the process of ml-service.
     438              :  */
     439              : int
     440            0 : ml_service_start (ml_service_h handle)
     441              : {
     442            0 :   ml_service_s *mls = (ml_service_s *) handle;
     443            0 :   int status = ML_ERROR_NONE;
     444              : 
     445            0 :   check_feature_state (ML_FEATURE_SERVICE);
     446              : 
     447            0 :   if (!_ml_service_handle_is_valid (mls)) {
     448            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     449              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     450              :   }
     451              : 
     452            0 :   switch (mls->type) {
     453            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
     454              :     {
     455            0 :       _ml_service_server_s *server = (_ml_service_server_s *) mls->priv;
     456              : 
     457            0 :       status = ml_agent_pipeline_start (server->id);
     458            0 :       if (status < 0)
     459            0 :         _ml_error_report ("Failed to invoke the method start_pipeline.");
     460              : 
     461            0 :       break;
     462              :     }
     463            0 :     case ML_SERVICE_TYPE_EXTENSION:
     464            0 :       status = ml_service_extension_start (mls);
     465            0 :       break;
     466            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     467            0 :       status = ml_service_offloading_start (mls);
     468            0 :       break;
     469            0 :     default:
     470              :       /* Invalid handle type. */
     471            0 :       status = ML_ERROR_NOT_SUPPORTED;
     472            0 :       break;
     473              :   }
     474              : 
     475            0 :   return status;
     476              : }
     477              : 
     478              : /**
     479              :  * @brief Stops the process of ml-service.
     480              :  */
     481              : int
     482            0 : ml_service_stop (ml_service_h handle)
     483              : {
     484            0 :   ml_service_s *mls = (ml_service_s *) handle;
     485            0 :   int status = ML_ERROR_NONE;
     486              : 
     487            0 :   check_feature_state (ML_FEATURE_SERVICE);
     488              : 
     489            0 :   if (!_ml_service_handle_is_valid (mls)) {
     490            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     491              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     492              :   }
     493              : 
     494            0 :   switch (mls->type) {
     495            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
     496              :     {
     497            0 :       _ml_service_server_s *server = (_ml_service_server_s *) mls->priv;
     498              : 
     499            0 :       status = ml_agent_pipeline_stop (server->id);
     500            0 :       if (status < 0)
     501            0 :         _ml_error_report ("Failed to invoke the method stop_pipeline.");
     502              : 
     503            0 :       break;
     504              :     }
     505            0 :     case ML_SERVICE_TYPE_EXTENSION:
     506            0 :       status = ml_service_extension_stop (mls);
     507            0 :       break;
     508            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     509            0 :       status = ml_service_offloading_stop (mls);
     510            0 :       break;
     511            0 :     default:
     512              :       /* Invalid handle type. */
     513            0 :       status = ML_ERROR_NOT_SUPPORTED;
     514            0 :       break;
     515              :   }
     516              : 
     517            0 :   return status;
     518              : }
     519              : 
     520              : /**
     521              :  * @brief Gets the information of required input data.
     522              :  */
     523              : int
     524            0 : ml_service_get_input_information (ml_service_h handle, const char *name,
     525              :     ml_tensors_info_h * info)
     526              : {
     527            0 :   ml_service_s *mls = (ml_service_s *) handle;
     528              :   int status;
     529              : 
     530            0 :   check_feature_state (ML_FEATURE_SERVICE);
     531              : 
     532            0 :   if (!_ml_service_handle_is_valid (mls)) {
     533            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     534              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     535              :   }
     536              : 
     537            0 :   if (!info) {
     538            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     539              :         "The parameter, info (ml_tensors_info_h), is NULL. It should be a valid pointer to create new instance.");
     540              :   }
     541              : 
     542              :   /* Init null. */
     543            0 :   *info = NULL;
     544              : 
     545            0 :   switch (mls->type) {
     546            0 :     case ML_SERVICE_TYPE_EXTENSION:
     547            0 :       status = ml_service_extension_get_input_information (mls, name, info);
     548            0 :       break;
     549            0 :     default:
     550              :       /* Invalid handle type. */
     551            0 :       status = ML_ERROR_NOT_SUPPORTED;
     552            0 :       break;
     553              :   }
     554              : 
     555            0 :   if (status != ML_ERROR_NONE) {
     556            0 :     if (*info) {
     557            0 :       ml_tensors_info_destroy (*info);
     558            0 :       *info = NULL;
     559              :     }
     560              :   }
     561              : 
     562            0 :   return status;
     563              : }
     564              : 
     565              : /**
     566              :  * @brief Gets the information of output data.
     567              :  */
     568              : int
     569            0 : ml_service_get_output_information (ml_service_h handle, const char *name,
     570              :     ml_tensors_info_h * info)
     571              : {
     572            0 :   ml_service_s *mls = (ml_service_s *) handle;
     573              :   int status;
     574              : 
     575            0 :   check_feature_state (ML_FEATURE_SERVICE);
     576              : 
     577            0 :   if (!_ml_service_handle_is_valid (mls)) {
     578            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     579              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     580              :   }
     581              : 
     582            0 :   if (!info) {
     583            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     584              :         "The parameter, info (ml_tensors_info_h), is NULL. It should be a valid pointer to create new instance.");
     585              :   }
     586              : 
     587              :   /* Init null. */
     588            0 :   *info = NULL;
     589              : 
     590            0 :   switch (mls->type) {
     591            0 :     case ML_SERVICE_TYPE_EXTENSION:
     592            0 :       status = ml_service_extension_get_output_information (mls, name, info);
     593            0 :       break;
     594            0 :     default:
     595              :       /* Invalid handle type. */
     596            0 :       status = ML_ERROR_NOT_SUPPORTED;
     597            0 :       break;
     598              :   }
     599              : 
     600            0 :   if (status != ML_ERROR_NONE) {
     601            0 :     if (*info) {
     602            0 :       ml_tensors_info_destroy (*info);
     603            0 :       *info = NULL;
     604              :     }
     605              :   }
     606              : 
     607            0 :   return status;
     608              : }
     609              : 
     610              : /**
     611              :  * @brief Sets the information for ml-service.
     612              :  */
     613              : int
     614            0 : ml_service_set_information (ml_service_h handle, const char *name,
     615              :     const char *value)
     616              : {
     617            0 :   ml_service_s *mls = (ml_service_s *) handle;
     618              :   int status;
     619              : 
     620            0 :   check_feature_state (ML_FEATURE_SERVICE);
     621              : 
     622            0 :   if (!_ml_service_handle_is_valid (mls)) {
     623            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     624              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     625              :   }
     626              : 
     627            0 :   if (!STR_IS_VALID (name)) {
     628            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     629              :         "The parameter, name '%s', is invalid.", name);
     630              :   }
     631              : 
     632            0 :   if (!STR_IS_VALID (value)) {
     633            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     634              :         "The parameter, value '%s', is invalid.", value);
     635              :   }
     636              : 
     637            0 :   g_mutex_lock (&mls->lock);
     638            0 :   status = _ml_service_set_information_internal (mls, name, value);
     639            0 :   g_mutex_unlock (&mls->lock);
     640              : 
     641            0 :   if (status != ML_ERROR_NONE) {
     642            0 :     _ml_error_report_return (status,
     643              :         "Failed to set the information '%s'.", name);
     644              :   }
     645              : 
     646            0 :   return ML_ERROR_NONE;
     647              : }
     648              : 
     649              : /**
     650              :  * @brief Gets the information from ml-service.
     651              :  */
     652              : int
     653            0 : ml_service_get_information (ml_service_h handle, const char *name, char **value)
     654              : {
     655            0 :   ml_service_s *mls = (ml_service_s *) handle;
     656            0 :   gchar *val = NULL;
     657              :   int status;
     658              : 
     659            0 :   check_feature_state (ML_FEATURE_SERVICE);
     660              : 
     661            0 :   if (!_ml_service_handle_is_valid (mls)) {
     662            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     663              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     664              :   }
     665              : 
     666            0 :   if (!STR_IS_VALID (name)) {
     667            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     668              :         "The parameter, name '%s', is invalid.", name);
     669              :   }
     670              : 
     671            0 :   if (!value) {
     672            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     673              :         "The parameter, value, is NULL. It should be a valid pointer.");
     674              :   }
     675              : 
     676            0 :   g_mutex_lock (&mls->lock);
     677            0 :   status = ml_option_get (mls->information, name, (void **) (&val));
     678            0 :   g_mutex_unlock (&mls->lock);
     679              : 
     680            0 :   if (status != ML_ERROR_NONE) {
     681            0 :     _ml_error_report_return (status,
     682              :         "The ml-service handle does not include the information '%s'.", name);
     683              :   }
     684              : 
     685            0 :   *value = g_strdup (val);
     686            0 :   return ML_ERROR_NONE;
     687              : }
     688              : 
     689              : /**
     690              :  * @brief Adds an input data to process the model in ml-service extension handle.
     691              :  */
     692              : int
     693            0 : ml_service_request (ml_service_h handle, const char *name,
     694              :     const ml_tensors_data_h data)
     695              : {
     696            0 :   ml_service_s *mls = (ml_service_s *) handle;
     697              :   int status;
     698              : 
     699            0 :   check_feature_state (ML_FEATURE_SERVICE);
     700              : 
     701            0 :   if (!_ml_service_handle_is_valid (mls)) {
     702            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     703              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     704              :   }
     705              : 
     706            0 :   if (!data) {
     707            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     708              :         "The parameter, data (ml_tensors_data_h), is NULL. It should be a valid ml_tensor_data_h instance, which is usually created by ml_tensors_data_create().");
     709              :   }
     710              : 
     711            0 :   switch (mls->type) {
     712            0 :     case ML_SERVICE_TYPE_EXTENSION:
     713            0 :       status = ml_service_extension_request (mls, name, data);
     714            0 :       break;
     715            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     716            0 :       status = ml_service_offloading_request (mls, name, data);
     717            0 :       break;
     718            0 :     default:
     719              :       /* Invalid handle type. */
     720            0 :       status = ML_ERROR_NOT_SUPPORTED;
     721            0 :       break;
     722              :   }
     723              : 
     724            0 :   return status;
     725              : }
     726              : 
     727              : /**
     728              :  * @brief Destroys the handle for machine learning service.
     729              :  */
     730              : int
     731            0 : ml_service_destroy (ml_service_h handle)
     732              : {
     733            0 :   ml_service_s *mls = (ml_service_s *) handle;
     734              : 
     735            0 :   check_feature_state (ML_FEATURE_SERVICE);
     736              : 
     737            0 :   if (!_ml_service_handle_is_valid (mls)) {
     738            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     739              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     740              :   }
     741              : 
     742            0 :   return _ml_service_destroy_internal (mls);
     743              : }
        

Generated by: LCOV version 2.0-1