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 {
* @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
* #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
* @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
/**
* @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);
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
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) {
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);
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;
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);
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;
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) {
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();
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);
}
/**
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;
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) {