From 552d3c3b47065e8a1048cb484102df884c21af5b Mon Sep 17 00:00:00 2001 From: Yongjoo Ahn Date: Thu, 4 Jul 2024 18:04:51 +0900 Subject: [PATCH] [Tizen] Add example app showing ml-service and rpk updates - Add a simple app showing how to use API `ml_service_new` and `ml_service_request`. - This app also demonstrate that how rpk updates can be used in AI app. Signed-off-by: Yongjoo Ahn --- Tizen.native/ml-service-example/README.md | 92 +++++ .../screenshot_with_rpk_v1.png | Bin 0 -> 32064 bytes .../screenshot_with_rpk_v2.png | Bin 0 -> 32379 bytes .../sum_and_add_app/.exportMap | 5 + .../sum_and_add_app/inc/sum_and_add.h | 19 + .../sum_and_add_app/project_def.prop | 11 + .../shared/res/sum_and_add.png | Bin 0 -> 57662 bytes .../sum_and_add_app/src/sum_and_add.c | 390 ++++++++++++++++++ .../sum_and_add_app/tizen-manifest.xml | 9 + .../res/global/sum_and_add/rpk_config.json | 2 +- .../res/global/sum_and_add/rpk_config.json | 2 +- 11 files changed, 528 insertions(+), 2 deletions(-) create mode 100644 Tizen.native/ml-service-example/README.md create mode 100644 Tizen.native/ml-service-example/screenshot_with_rpk_v1.png create mode 100644 Tizen.native/ml-service-example/screenshot_with_rpk_v2.png create mode 100644 Tizen.native/ml-service-example/sum_and_add_app/.exportMap create mode 100644 Tizen.native/ml-service-example/sum_and_add_app/inc/sum_and_add.h create mode 100644 Tizen.native/ml-service-example/sum_and_add_app/project_def.prop create mode 100644 Tizen.native/ml-service-example/sum_and_add_app/shared/res/sum_and_add.png create mode 100644 Tizen.native/ml-service-example/sum_and_add_app/src/sum_and_add.c create mode 100644 Tizen.native/ml-service-example/sum_and_add_app/tizen-manifest.xml diff --git a/Tizen.native/ml-service-example/README.md b/Tizen.native/ml-service-example/README.md new file mode 100644 index 00000000..2ab231ff --- /dev/null +++ b/Tizen.native/ml-service-example/README.md @@ -0,0 +1,92 @@ +# Example of using ML Service APIs with RPKs + +## org.example.sum_and_add + +This app prints invoke results of `sum_and_add` model from rpk. Depend on the rpk version, the output should be different. + +## RPK "org.resource.model.sum_and_add" v1 + +This RPK contains `sum_and_add` model file, `sum_and_add_one.tflite`. Made by this python script: + +```python +import torch +import ai_edge_torch + +class AddModelOne(torch.nn.Module): + def __init__(self): + super().__init__() + + def forward(self, input_tensor): + output = torch.sum(input_tensor, (1)) + 1.0 + return output # sum all value of input tensor and add 1.0 + +sum_and_add_one = AddModelOne().eval() +sum_and_add_one(torch.tensor([[1.0, 2.0, 3.0, 4.0]])) # output: tensor([11.]) + +sample_inputs = (torch.randn(1, 4),) # restrict the shape of input as (1, 4) +edge_model = ai_edge_torch.convert(sum_and_add_one, sample_inputs) # convert the model +edge_model(torch.tensor([[1.0, 2.0, 3.0, 4.0]])) # validate the output: tensor([11.]) +edge_model.export("sum_and_add_one.tflite") # save as tflite model file +``` + +## RPK "org.resource.model.sum_and_add" v2 + +This RPK contains `sum_and_add` model file, `sum_and_add_two.tflite`. Made by: + +```python +class AddModelTwo(torch.nn.Module): + def __init__(self): + super().__init__() + + def forward(self, input_tensor): + output = torch.sum(input_tensor, (1)) + 2.0 + return output # sum all value of input tensor and add 2.0 + +sum_and_add_two = AddModelTwo().eval() +sum_and_add_two(torch.tensor([[1.0, 2.0, 3.0, 4.0]])) # output: tensor([12.]) + +sample_inputs = (torch.randn(1, 4),) # restrict the shape of input as (1, 4) +edge_model = ai_edge_torch.convert(sum_and_add_two, sample_inputs) # convert the model +edge_model(torch.tensor([[1.0, 2.0, 3.0, 4.0]])) # validate the output: tensor([12.]) +edge_model.export("sum_and_add_two.tflite") # save as tflite model file +``` + +## Scenario + +The app `org.example.sum_and_add` uses AI defined in the RPK `org.resource.model.sum_and_add`. + +1. install RPK `org.resource.model.sum_and_add` V1 + + ```bash + cd sum_and_add_model_rpk_v1 + tizen package -t rpk -- . + tizen install -n "./Package/org.resource.model.sum_and_add-1.0.0.rpk" + ``` + +2. Install and run the app `org.example.sum_and_add` + + ```bash + cd sum_and_add_app + tizen build-native -r tizen-9.0-device64.core -- . + tizen package -t tpk -- ./Debug + tizen install -n "./Debug/org.example.sum_and_add-1.0.0-aarch64.tpk" + tizen run -p "org.example.sum_and_add" + ``` + + ![v1](./screenshot_with_rpk_v1.png) + +3. Update the RPK with V2 and run the app again + + ```bash + cd sum_and_add_model_rpk_v2 + tizen package -t rpk -- . + tizen install -n "./Package/org.resource.model.sum_and_add-2.0.0.rpk" + tizen run -p "org.example.sum_and_add" + ``` + + The result of app is changed: + ![v2](./screenshot_with_rpk_v2.png) + +## Note + +The app `org.example.sum_and_add` is packaged and deployed only once. Developers can update the app's AI model with RPK update. diff --git a/Tizen.native/ml-service-example/screenshot_with_rpk_v1.png b/Tizen.native/ml-service-example/screenshot_with_rpk_v1.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4cf31963eefdd4bf1c2c4a8355391155175a03 GIT binary patch literal 32064 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 literal 0 HcmV?d00001 diff --git a/Tizen.native/ml-service-example/screenshot_with_rpk_v2.png b/Tizen.native/ml-service-example/screenshot_with_rpk_v2.png new file mode 100644 index 0000000000000000000000000000000000000000..57e70aea4857b1437f4badfa0f8aa1e229d3d26d GIT binary patch literal 32379 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�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 WHpi6Om$VV*X=Hflx7=N)F8>#}%U?AB literal 0 HcmV?d00001 diff --git a/Tizen.native/ml-service-example/sum_and_add_app/.exportMap b/Tizen.native/ml-service-example/sum_and_add_app/.exportMap new file mode 100644 index 00000000..de305161 --- /dev/null +++ b/Tizen.native/ml-service-example/sum_and_add_app/.exportMap @@ -0,0 +1,5 @@ +{ + global: main; + _IO_*; + local: *; +}; diff --git a/Tizen.native/ml-service-example/sum_and_add_app/inc/sum_and_add.h b/Tizen.native/ml-service-example/sum_and_add_app/inc/sum_and_add.h new file mode 100644 index 00000000..fd924463 --- /dev/null +++ b/Tizen.native/ml-service-example/sum_and_add_app/inc/sum_and_add.h @@ -0,0 +1,19 @@ +#ifndef __sum_and_add_H__ +#define __sum_and_add_H__ + +#include +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "sum_and_add" + +#if !defined(PACKAGE) +#define PACKAGE "org.example.sum_and_add" +#endif + +#endif /* __sum_and_add_H__ */ diff --git a/Tizen.native/ml-service-example/sum_and_add_app/project_def.prop b/Tizen.native/ml-service-example/sum_and_add_app/project_def.prop new file mode 100644 index 00000000..c846b449 --- /dev/null +++ b/Tizen.native/ml-service-example/sum_and_add_app/project_def.prop @@ -0,0 +1,11 @@ +APPNAME = sum_and_add + +type = app +profile = tizeniot-9.0 + +USER_SRCS = src/sum_and_add.c +USER_DEFS = +USER_INC_DIRS = inc +USER_OBJS = +USER_LIBS = +USER_EDCS = diff --git a/Tizen.native/ml-service-example/sum_and_add_app/shared/res/sum_and_add.png b/Tizen.native/ml-service-example/sum_and_add_app/shared/res/sum_and_add.png new file mode 100644 index 0000000000000000000000000000000000000000..9765b1bda7e5bddf0925555ab204b887a873bf24 GIT binary patch literal 57662 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 kZ}gYfNaCF}xV$|1>H6z0+kD + * @bug No known bugs except for NYI items. + */ + +#include "sum_and_add.h" +#include +#include +#include +#include + +/** @brief UI and ml-service related objects */ +typedef struct appdata { + Evas_Object *win; + Evas_Object *conform; + Evas_Object *head_label; + Evas_Object *info_label; + Evas_Object *desc_label; + Evas_Object *input_label; + Evas_Object *result_label; + + int is_running; + pthread_t request_loop; + + ml_service_h service_handle; + ml_tensors_info_h input_info; + ml_tensors_info_h output_info; + ml_tensors_data_h input_data_h; + +} appdata_s; + +Ecore_Pipe *data_output_pipe; + +/** @brief Invoke ml_service evey 1 sec */ +static void * +_invoke_request_loop (void *user_data) +{ + appdata_s *ad = (appdata_s *) user_data; + while (1) { + if (ad->is_running == 1) { + ml_service_request (ad->service_handle, NULL, ad->input_data_h); + } + + g_usleep (1000 * 1000); /* request every 1 sec */ + } +} + +/** @brief Return informative string of given tensors_info */ +static char * +tensors_info_to_string (ml_tensors_info_h info) +{ + unsigned int count; + GString *ret_str = g_string_new (NULL); + + ml_tensors_info_get_count (info, &count); + g_string_append_printf (ret_str, " - tensor count: %u\n
", count); + + for (guint idx = 0; idx < count; idx++){ + g_string_append_printf (ret_str, " - tensor[%u]\n
", idx); + gchar *name; + ml_tensors_info_get_tensor_name (info, idx, &name); + g_string_append_printf (ret_str, " - name: %s\n
", name); + g_free (name); + + ml_tensor_type_e type; + ml_tensors_info_get_tensor_type (info, idx, &type); + g_string_append_printf (ret_str, " - type: %d\n
", type); + + ml_tensor_dimension dimension; + ml_tensors_info_get_tensor_dimension (info, idx, dimension); + for (int j = 0; j < ML_TENSOR_RANK_LIMIT; j++) { + g_string_append_printf (ret_str, " - dimension[%d]: %d\n
", j, dimension[j]); + if (dimension[j] == 0) + break; + } + + size_t size; + ml_tensors_info_get_tensor_size (info, idx, &size); + g_string_append_printf (ret_str, " - size: %zu byte\n
", size); + } + + return g_string_free (ret_str, FALSE); +} + +/** @brief event callback */ +static void +_event_cb (ml_service_event_e event, ml_information_h event_data, void *user_data) +{ + ml_tensors_data_h new_data = NULL; + + if (event != ML_SERVICE_EVENT_NEW_DATA) + return; + + // get tensors-data from event data. + ml_information_get (event_data, "data", &new_data); + + // get the float result + float *result; + size_t result_size; + int ret = ml_tensors_data_get_tensor_data (new_data, 0U, (void *) &result, &result_size); + if (ret != ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_tensors_data_get_tensor_data failed"); + return; + } + + // do something useful with the result. + ecore_pipe_write (data_output_pipe, (void *) result, result_size); +} + +/** @brief base code for basic UI app */ +static void +win_delete_request_cb (void *data, Evas_Object *obj, void *event_info) +{ + ui_app_exit (); +} + +/** @brief base code for basic UI app */ +static void +win_back_cb (void *data, Evas_Object *obj, void *event_info) +{ + appdata_s *ad = data; + elm_win_lower (ad->win); +} + +/** @brief base code for basic UI app */ +static void +update_gui (void *data, void *buf, unsigned int size) +{ + appdata_s *ad = data; + float *result = (float *) buf; + + gchar *tt = g_strdup_printf ( + "Result of [sum_and_add] is %.1f", *result); + + elm_object_text_set (ad->result_label, tt); + g_free (tt); +} + +/** @brief Creates essential UI objects */ +static void +create_base_gui (appdata_s *ad) +{ + ad->win = elm_win_util_standard_add (PACKAGE, PACKAGE); + elm_win_autodel_set (ad->win, EINA_TRUE); + + if (elm_win_wm_rotation_supported_get (ad->win)) { + int rots[4] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set (ad->win, (const int *) (&rots), 4); + } + evas_object_smart_callback_add (ad->win, "delete,request", win_delete_request_cb, NULL); + eext_object_event_callback_add (ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad); + + ad->conform = elm_conformant_add (ad->win); + elm_win_indicator_mode_set (ad->win, ELM_WIN_INDICATOR_SHOW); + elm_win_indicator_opacity_set (ad->win, ELM_WIN_INDICATOR_OPAQUE); + evas_object_size_hint_weight_set (ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add (ad->win, ad->conform); + evas_object_show (ad->conform); + + ad->head_label = elm_label_add (ad->conform); + elm_object_text_set (ad->head_label, "Hello Tizen ML Service API"); + evas_object_move (ad->head_label, 120, 80); + evas_object_resize (ad->head_label, 600, 80); + evas_object_show (ad->head_label); + + ad->info_label = elm_label_add (ad->conform); + elm_object_text_set (ad->info_label, ""); + evas_object_move (ad->info_label, 30, 200); + evas_object_resize (ad->info_label, 400, 400); + evas_object_show (ad->info_label); + + ad->desc_label = elm_label_add (ad->conform); + elm_object_text_set (ad->desc_label, ""); + evas_object_move (ad->desc_label, 300, 200); + evas_object_resize (ad->desc_label, 600, 100); + evas_object_show (ad->desc_label); + + ad->input_label = elm_label_add (ad->conform); + elm_object_text_set (ad->input_label, ""); + evas_object_move (ad->input_label, 300, 300); + evas_object_resize (ad->input_label, 600, 100); + evas_object_show (ad->input_label); + + ad->result_label = elm_label_add (ad->conform); + elm_object_text_set (ad->result_label, ""); + evas_object_move (ad->result_label, 300, 350); + evas_object_resize (ad->result_label, 600, 100); + evas_object_show (ad->result_label); + + evas_object_show (ad->win); +} + +/** @brief Destroy the ml_service and related elements */ +void +terminate_ml_service (appdata_s *ad) +{ + ad->is_running = 0; + g_usleep (1000 * 1000); + pthread_join (ad->request_loop, NULL); + ml_tensors_info_destroy (ad->input_info); + ml_tensors_info_destroy (ad->output_info); + ml_service_destroy (ad->service_handle); +} + +/** @brief Initialize the ml_service path */ +int +init_ml_service (appdata_s *ad) +{ + int status = -1; + // const gchar *key = "sum_and_add"; + gchar *conf_file_path = NULL; + ml_information_list_h res_info_list; + + // get conf file from rpk + status = ml_service_resource_get ("sum_and_add_resource_conf", &res_info_list); + unsigned int info_length = 0U; + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "Failed to get resource data"); + return status; + } + + // the conf file is the first item of `res_info_list` + ml_information_list_length (res_info_list, &info_length); + for (int i = 0; i < info_length; i++) { + ml_information_h info; + status = ml_information_list_get (res_info_list, i, &info); + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_information_list_get failed"); + } + char *path = NULL; + status = ml_information_get (info, "path", (void **) &path); + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_information_get failed"); + } + conf_file_path = g_strdup (path); + } + + ml_information_list_destroy (res_info_list); + + if (!g_file_test (conf_file_path, (G_FILE_TEST_EXISTS))) { + dlog_print (DLOG_ERROR, LOG_TAG, "conf file does not exist!"); + return -1; + } + + // make ml_service + status = ml_service_new (conf_file_path, &ad->service_handle); + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_service_new failed"); + return status; + } + + // get input information + status = ml_service_get_input_information (ad->service_handle, NULL, &ad->input_info); + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_service_get_input_information failed"); + return status; + } + + // get output information + status = ml_service_get_output_information (ad->service_handle, NULL, &ad->output_info); + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_service_get_output_information failed"); + return status; + } + + // set new_data callback + status = ml_service_set_event_cb (ad->service_handle, _event_cb, NULL); + if (status!= ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_service_set_event_cb failed"); + return status; + } + + // show tensors_info + gchar *input_info_str = tensors_info_to_string (ad->input_info); + gchar *output_info_str = tensors_info_to_string (ad->output_info); + gchar *info_value_text = g_strdup_printf ("Input tensors info:
%s
output tensors info:
%s", input_info_str, output_info_str); + elm_object_text_set (ad->info_label, info_value_text); + g_free (input_info_str); + g_free (output_info_str); + + // show information of the serivce + gchar *description = NULL; + status = ml_service_get_information (ad->service_handle, "description", &description); + gchar *info_desc_text = g_strdup_printf ("Description:
%s", description); + elm_object_text_set (ad->desc_label, info_desc_text); + g_free (description); + + // set input data + ml_tensors_data_create (ad->input_info, &ad->input_data_h); + float input_arr[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; + + // set 0-th tensor data with given buffer + status = ml_tensors_data_set_tensor_data (ad->input_data_h, 0U, (uint8_t *) input_arr, 4 * sizeof (float)); + if (status != ML_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "ml_tensors_data_set_tensor_data failed"); + return status; + } + + // show input tensor value + gchar *input_tensor_value_text = g_strdup_printf ("Input tensor = float { %.1f, %.1f, %.1f, %.1f }", input_arr[0], input_arr[1], input_arr[2], input_arr[3]); + elm_object_text_set (ad->input_label, input_tensor_value_text); + g_free (input_tensor_value_text); + + // set loop + ad->is_running = 0; + status = pthread_create (&ad->request_loop, NULL, _invoke_request_loop, ad); + if (status != 0) { + dlog_print (DLOG_ERROR, LOG_TAG, "pthread_create failed"); + return status; + } + + return status; +} + +/** @brief base code for basic UI app */ +static bool +app_create (void *data) +{ + appdata_s *ad = data; + + data_output_pipe = ecore_pipe_add ((Ecore_Pipe_Cb) update_gui, ad); + if (!data_output_pipe) { + dlog_print (DLOG_ERROR, LOG_TAG, "Failed to create data output pipe"); + } + + create_base_gui (ad); + init_ml_service (ad); + + return true; +} + +/** @brief base code for basic UI app */ +static void +app_control (app_control_h app_control, void *data) +{ + return; +} + +/** @brief base code for basic UI app */ +static void +app_pause (void *data) +{ + appdata_s *ad = data; + ad->is_running = 0; +} + +/** @brief base code for basic UI app */ +static void +app_resume (void *data) +{ + appdata_s *ad = data; + ad->is_running = 1; +} + +/** @brief base code for basic UI app */ +static void +app_terminate (void *data) +{ + appdata_s *ad = data; + ecore_pipe_del (data_output_pipe); + terminate_ml_service (ad); +} + +/** @brief base code for basic UI app */ +int +main(int argc, char *argv[]) +{ + appdata_s ad = {0,}; + int ret = 0; + + ui_app_lifecycle_callback_s event_callback = {0,}; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + ret = ui_app_main (argc, argv, &event_callback, &ad); + if (ret != APP_ERROR_NONE) { + dlog_print (DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret); + } + + return ret; +} diff --git a/Tizen.native/ml-service-example/sum_and_add_app/tizen-manifest.xml b/Tizen.native/ml-service-example/sum_and_add_app/tizen-manifest.xml new file mode 100644 index 00000000..094d935d --- /dev/null +++ b/Tizen.native/ml-service-example/sum_and_add_app/tizen-manifest.xml @@ -0,0 +1,9 @@ + + + + + sum_and_add.png + + + + diff --git a/Tizen.native/ml-service-example/sum_and_add_model_rpk_v1/res/global/sum_and_add/rpk_config.json b/Tizen.native/ml-service-example/sum_and_add_model_rpk_v1/res/global/sum_and_add/rpk_config.json index ac6d6d19..39ea21e5 100644 --- a/Tizen.native/ml-service-example/sum_and_add_model_rpk_v1/res/global/sum_and_add/rpk_config.json +++ b/Tizen.native/ml-service-example/sum_and_add_model_rpk_v1/res/global/sum_and_add/rpk_config.json @@ -14,4 +14,4 @@ "description" : "Notes for this conf file" } ] -} \ No newline at end of file +} diff --git a/Tizen.native/ml-service-example/sum_and_add_model_rpk_v2/res/global/sum_and_add/rpk_config.json b/Tizen.native/ml-service-example/sum_and_add_model_rpk_v2/res/global/sum_and_add/rpk_config.json index 7e44b1ef..2c634f43 100644 --- a/Tizen.native/ml-service-example/sum_and_add_model_rpk_v2/res/global/sum_and_add/rpk_config.json +++ b/Tizen.native/ml-service-example/sum_and_add_model_rpk_v2/res/global/sum_and_add/rpk_config.json @@ -14,4 +14,4 @@ "description" : "Notes for this conf file" } ] -} \ No newline at end of file +}