From 83a1b6189f591e3d87694a0900f670524e29cf0a Mon Sep 17 00:00:00 2001 From: Jihoon Lee Date: Thu, 8 Oct 2020 15:53:07 +0900 Subject: [PATCH] [CS/Refactor] Scrape ecore pipe from the train_ **Changes proposed in this PR:** - Ecore Pipe is no longer used to update UI - Broaden the canvas to make it easier to draw - s/tries/epoch for training progress - Minor bug fix that was generating warnings **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Jihoon Lee --- .../Tizen_native/CustomShortcut/inc/data.h | 18 +++++----- .../Tizen_native/CustomShortcut/inc/view.h | 10 +++--- .../Tizen_native/CustomShortcut/src/data.c | 36 +++++++------------- .../Tizen_native/CustomShortcut/src/main.c | 38 +++++++++------------- .../Tizen_native/CustomShortcut/src/view.c | 31 ++++++------------ 5 files changed, 51 insertions(+), 82 deletions(-) diff --git a/Applications/Tizen_native/CustomShortcut/inc/data.h b/Applications/Tizen_native/CustomShortcut/inc/data.h index f1d0d71..6079e27 100644 --- a/Applications/Tizen_native/CustomShortcut/inc/data.h +++ b/Applications/Tizen_native/CustomShortcut/inc/data.h @@ -82,11 +82,12 @@ typedef struct appdata { pthread_cond_t pipe_cond; /**< pipe condition to block at a point */ /**< Training related */ - pthread_t tid_writer; /**< thread handler to run trainer */ - pthread_t tid_reader; /**< thread handler to read train result */ - int pipe_fd[2]; /**< fd for pipe */ - Ecore_Pipe *data_output_pipe; /**< pipe to write information to ui */ - double best_accuracy; /**< stores best accuracy */ + pthread_t tid_writer; /**< thread handler to run trainer */ + pthread_t tid_reader; /**< thread handler to read train result */ + int pipe_fd[2]; /**< fd for pipe */ + double best_accuracy; /**< stores best accuracy */ + unsigned int current_epoch; /**< current epoch */ + double train_loss; /**< current loss */ } appdata_s; typedef struct train_result { @@ -173,9 +174,10 @@ void *data_run_model(void *ad); * @brief nntrainer update train result from data_run_model * * @param[in] ad appdata - * @return not used + * @param[in] buf buffer hooked from stdout + * @return APP_ERROR_NONE if suceess */ -void *data_update_train_result(void *ad); +int data_update_train_progress(appdata_s *ad, const char *buf); /** * @brief parse result string @@ -190,7 +192,7 @@ void *data_update_train_result(void *ad); * #10/10 - Training Loss: 0.398767 >> [ Accuracy: 75% - Validation Loss : 0.467543 ] */ -int data_parse_result_string(const char *src, train_result_s *train_result); +int util_parse_result_string(const char *src, train_result_s *train_result); /** * @brief run inference with nnstreamer diff --git a/Applications/Tizen_native/CustomShortcut/inc/view.h b/Applications/Tizen_native/CustomShortcut/inc/view.h index 224ed3c..6f74cf2 100644 --- a/Applications/Tizen_native/CustomShortcut/inc/view.h +++ b/Applications/Tizen_native/CustomShortcut/inc/view.h @@ -31,7 +31,7 @@ int view_init(appdata_s *ad); * @param[in] ad appdata * @param[in] to pop until to is meet, if NULL pops only one time */ -void view_pop_naviframe(appdata_s *ad, const Elm_Object_Item *to); +void view_pop_naviframe(appdata_s *ad, Elm_Object_Item *to); /** * @brief initiate canvas @@ -57,17 +57,15 @@ void view_set_canvas_clean(appdata_s *ad); /** * @brief callback function to update training result - * @param[in] data user data - * @param[in] buffer arrays of null terminated characters - * @param[in] nbytes max length of the buffer + * @param[in] data appdata + * @return Not used */ -void view_update_result_cb(void *data, void *buffer, unsigned int nbytes); +void *view_update_train_progress(void *data); /** * @brief update guess from the inference result * * @param[in] ad appdata - * @return int APP_ERROR_NONE if success */ void view_update_guess(void *ad); diff --git a/Applications/Tizen_native/CustomShortcut/src/data.c b/Applications/Tizen_native/CustomShortcut/src/data.c index a5e7ff6..bd3eed6 100644 --- a/Applications/Tizen_native/CustomShortcut/src/data.c +++ b/Applications/Tizen_native/CustomShortcut/src/data.c @@ -465,37 +465,25 @@ CLEAN_UP: return NULL; } -void *data_update_train_result(void *data) { - appdata_s *ad = (appdata_s *)data; - - // run model in another thread - int read_fd = ad->pipe_fd[0]; - FILE *fp; - char buf[255]; - - fp = fdopen(read_fd, "r"); - - LOG_D("start waiting to get result"); +int data_update_train_progress(appdata_s *ad, const char *buf) { + train_result_s result; - ecore_pipe_thaw(ad->data_output_pipe); + if (util_parse_result_string(buf, &result) != 0) { + LOG_W("parse failed. current buffer is being ignored"); + return APP_ERROR_INVALID_PARAMETER; + } - while (fgets(buf, 255, fp) != NULL) { - if (ecore_pipe_write(ad->data_output_pipe, buf, 255) == false) { - LOG_E("pipe write error"); - return NULL; - }; + if (result.accuracy > ad->best_accuracy) { + ad->best_accuracy = result.accuracy; } - LOG_D("training finished"); - fclose(fp); - close(read_fd); - sleep(1); - ecore_pipe_freeze(ad->data_output_pipe); + ad->current_epoch = result.epoch; + ad->train_loss = result.train_loss; - return NULL; + return APP_ERROR_NONE; } -int data_parse_result_string(const char *src, train_result_s *train_result) { +int util_parse_result_string(const char *src, train_result_s *train_result) { // clang-format off // #10/10 - Training Loss: 0.398767 >> [ Accuracy: 75% - Validation Loss : 0.467543 ] // clang-format on diff --git a/Applications/Tizen_native/CustomShortcut/src/main.c b/Applications/Tizen_native/CustomShortcut/src/main.c index 12581c3..124f51a 100644 --- a/Applications/Tizen_native/CustomShortcut/src/main.c +++ b/Applications/Tizen_native/CustomShortcut/src/main.c @@ -63,14 +63,15 @@ static void notify_train_done(void *data) { static void *train_(void *data) { int status = ML_ERROR_NONE; appdata_s *ad = (appdata_s *)data; + FILE *fp; + char buf[255]; + status = pipe(ad->pipe_fd); if (status < 0) { LOG_E("opening pipe for training failed"); goto RESTORE_CB; } - ad->best_accuracy = 0.0; - LOG_D("creating thread to run model"); status = pthread_create(&ad->tid_writer, NULL, data_run_model, (void *)ad); if (status < 0) { @@ -78,18 +79,17 @@ static void *train_(void *data) { goto RESTORE_CB; } - status = - pthread_create(&ad->tid_reader, NULL, data_update_train_result, (void *)ad); - if (status < 0) { - LOG_E("creating pthread failed %s", strerror(errno)); - pthread_cancel(ad->tid_writer); - goto RESTORE_CB; - } + LOG_D("prepare to update the progress"); + ad->best_accuracy = 0.0; + fp = fdopen(ad->pipe_fd[0], "r"); - status = pthread_join(ad->tid_reader, NULL); - if (status < 0) { - LOG_E("joining reader thread failed %s", strerror(errno)); - pthread_cancel(ad->tid_reader); + while (fgets(buf, 255, fp) != NULL) { + status = data_update_train_progress(ad, buf); + if (status != APP_ERROR_NONE) { + LOG_W("updating training progress failed"); + continue; + } + ecore_main_loop_thread_safe_call_sync(view_update_train_progress, data); } status = pthread_join(ad->tid_writer, NULL); @@ -98,6 +98,8 @@ static void *train_(void *data) { pthread_cancel(ad->tid_writer); } + fclose(fp); + close(ad->pipe_fd[0]); RESTORE_CB: ecore_main_loop_thread_safe_call_async(¬ify_train_done, data); return NULL; @@ -288,13 +290,6 @@ static bool app_create(void *data) { pthread_mutex_init(&ad->pipe_lock, NULL); pthread_cond_init(&ad->pipe_cond, NULL); - ad->data_output_pipe = ecore_pipe_add(view_update_result_cb, (void *)ad); - if (ad->data_output_pipe == NULL) { - LOG_E("making data out pipe failed"); - free(data_path); - return false; - } - util_get_resource_path(EDJ_PATH, ad->edj_path, false); LOG_D("changing root directory to %s", data_path); @@ -312,8 +307,6 @@ static bool app_create(void *data) { eext_naviframe_more_cb, NULL); presenter_on_routes_request(data, NULL, NULL, "home"); - - LOG_D("layout: %x, nf_it: %x", ad->layout, ad->nf_it); ad->home = ad->nf_it; return true; @@ -339,7 +332,6 @@ static void app_terminate(void *data) { /* Release all resources. */ pthread_mutex_destroy(&ad->pipe_lock); pthread_cond_destroy(&ad->pipe_cond); - ecore_pipe_del(ad->data_output_pipe); } static void ui_app_lang_changed(app_event_info_h event_info, void *user_data) { diff --git a/Applications/Tizen_native/CustomShortcut/src/view.c b/Applications/Tizen_native/CustomShortcut/src/view.c index 044347c..09018d5 100644 --- a/Applications/Tizen_native/CustomShortcut/src/view.c +++ b/Applications/Tizen_native/CustomShortcut/src/view.c @@ -76,12 +76,10 @@ int view_init(appdata_s *ad) { ad->win = win; ad->conform = conform; - ecore_pipe_freeze(ad->data_output_pipe); - return status; } -void view_pop_naviframe(appdata_s *ad, const Elm_Object_Item *to) { +void view_pop_naviframe(appdata_s *ad, Elm_Object_Item *to) { if (ad->nf_it == NULL || ad->nf_it == ad->home) { LOG_E("naviframe is null or at home, shutdown app instead"); ui_app_exit(); @@ -97,7 +95,6 @@ void view_pop_naviframe(appdata_s *ad, const Elm_Object_Item *to) { ad->nf_it = elm_naviframe_top_item_get(ad->naviframe); ad->layout = elm_object_item_part_content_get(ad->nf_it, "elm.swallow.content"); - LOG_D("item popped layout: %x nf_it: %x", ad->layout, ad->nf_it); } /** @@ -257,8 +254,8 @@ int view_init_canvas(appdata_s *ad) { return APP_ERROR_INVALID_PARAMETER; } - evas_object_move(frame, 70, 70); - evas_object_resize(frame, 224, 224); + evas_object_move(frame, 0, 70); + evas_object_resize(frame, 360, 224); evas_object_show(frame); Evas_Coord width, height, x, y; @@ -337,28 +334,20 @@ int view_init_canvas(appdata_s *ad) { return APP_ERROR_NONE; } -void view_update_result_cb(void *data, void *buffer, unsigned int nbytes) { +void *view_update_train_progress(void *data) { appdata_s *ad = (appdata_s *)data; - char tmp[255]; - train_result_s result; - if (data_parse_result_string(buffer, &result) != 0) { - LOG_W("parse failed. current buffer is being ignored"); - return; - } + snprintf(tmp, 255, "%.0f%%", ad->best_accuracy); + elm_object_part_text_set(ad->layout, "train_progress/accuracy", tmp); - if (result.accuracy > ad->best_accuracy) { - ad->best_accuracy = result.accuracy; - snprintf(tmp, 255, "%.0f%%", ad->best_accuracy); - elm_object_part_text_set(ad->layout, "train_progress/accuracy", tmp); - } - - snprintf(tmp, 255, "%d tries", result.epoch); + snprintf(tmp, 255, "%d epoch", ad->current_epoch); elm_object_part_text_set(ad->layout, "train_progress/epoch", tmp); - snprintf(tmp, 255, "Loss: %.2f", result.train_loss); + snprintf(tmp, 255, "Loss: %.2f", ad->train_loss); elm_object_part_text_set(ad->layout, "train_progress/loss", tmp); + + return NULL; } void view_update_guess(void *data) { -- 2.7.4