[CS] Show inference
authorJihoon Lee <jhoon.it.lee@samsung.com>
Mon, 28 Sep 2020 11:44:22 +0000 (20:44 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 6 Oct 2020 04:50:30 +0000 (13:50 +0900)
This patch shows inference to the page after evaluation.

**Self evaluation:**
1. Build test: [X]Passed [ ]Failed [ ]Skipped
2. Run test: [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: Jihoon Lee <jhoon.it.lee@samsung.com>
Applications/Tizen_native/CustomShortcut/inc/data.h
Applications/Tizen_native/CustomShortcut/inc/view.h
Applications/Tizen_native/CustomShortcut/res/edje/main.edc
Applications/Tizen_native/CustomShortcut/src/data.c
Applications/Tizen_native/CustomShortcut/src/main.c
Applications/Tizen_native/CustomShortcut/src/view.c

index 1540c25fd3951d2409debba7b236fd61c5fb3df4..92f6b1f713d5e7a260663ad0a86315e5559f3e15 100644 (file)
@@ -127,6 +127,15 @@ int util_get_resource_path(const char *file, char *full_path, bool shared);
  */
 int util_save_drawing(cairo_surface_t *cr_surface, const char *dst);
 
+/**
+ * @brief get emoji string from LABEL enum
+ *
+ * @param[in] label label allocate outside.
+ * @param[out] emoji_str string emoticon from the enum. free after use
+ * @return int APP_ERROR_NONE if success;
+ */
+int util_get_emoji(LABEL label, char **emoji_str);
+
 /**
  * @brief handle given path_data. If data is invalid, it is essentially noop
  *
index 7f57751b3929023ae0febdffd587ef7a85e6e83d..8432a848194f16aea83642155fc8bc2974953ae4 100644 (file)
@@ -62,4 +62,12 @@ void view_set_canvas_clean(appdata_s *ad);
  */
 void view_update_result_cb(void *data, void *buffer, unsigned int nbytes);
 
+/**
+ * @brief update guess from the inference result
+ *
+ * @param[in] ad appdata
+ * @return int APP_ERROR_NONE if success
+ */
+void view_update_guess(void *ad);
+
 #endif /* __nntrainer_example_custom_shortcut_view_H__ */
index 3f441c7d39cb5a6909e841cb40cd3f3bd9887949..38e97fe12f29e0a422aaccf1bf82205bf7e38316 100644 (file)
@@ -207,9 +207,20 @@ collections {
   group {
     name: "test_result";
     parts {
-      PART_TITLE("test_result/title", "eval successfully done")
-      PART_BUTTON("test_result/go_back", "😊", 0.1, 0.3, 0.9, 0.7)
-      // reserve a text area to show the guess from the model
+      PART_TITLE("test_result/title", "eval in progress")
+      part {
+        name: "test_result/label";
+        type: TEXT;
+        description {
+          state: "default" 0.0;
+          rel1.relative: 0.0 0.2;
+          rel2.relative: 1.0 0.8;
+          text {
+            text: "Guess...";
+            size: 100;
+            align: 0.5 0.5;
+          }
+        }
     }
   }
 }
index 984d057afc880c9fcd4db1c6a1d5f843cdcd1b90..678f85ee8dccf280654978e8f5a76043a2c5a0e1 100644 (file)
@@ -109,6 +109,29 @@ int util_save_drawing(cairo_surface_t *cr_surface, const char *dst) {
   return APP_ERROR_NONE;
 }
 
+int util_get_emoji(LABEL label, char **emoji_str) {
+  *emoji_str = (char *)malloc(sizeof(char) * 5);
+
+  /// setting draw label and text
+  switch (label) {
+  case LABEL_UNSET:
+    strcpy(*emoji_str, "❓");
+    return APP_ERROR_NONE;
+  case LABEL_SMILE:
+    strcpy(*emoji_str, "😊");
+    return APP_ERROR_NONE;
+  case LABEL_FROWN:
+    strcpy(*emoji_str, "😢");
+    return APP_ERROR_NONE;
+  default:
+    LOG_E("unreachable code");
+    return APP_ERROR_INVALID_CONTEXT;
+  }
+  return APP_ERROR_INVALID_CONTEXT;
+}
+
+/************** data releated methods **********************/
+
 static void on_feature_receive_(ml_tensors_data_h data,
                                 const ml_tensors_info_h info, void *user_data) {
   appdata_s *ad = (appdata_s *)user_data;
@@ -533,6 +556,7 @@ static void on_inference_end_(ml_tensors_data_h data,
   /// SMILE: 0 1
   /// FROWN: 1 0
   LOG_D("label: %lf %lf", raw_data[0], raw_data[1]);
+  ad->label = raw_data[0] < raw_data[1] ? LABEL_SMILE : LABEL_FROWN;
 
 RESUME:
   status = pthread_cond_signal(&ad->pipe_cond);
index ab4c7624eaee66fbe1dd10dffc9e6ea09162a1c6..f577991ae4b649442a84bac64e60b58461ad7577 100644 (file)
@@ -100,6 +100,20 @@ static void *train_(void *data) {
 
 RESTORE_CB:
   ecore_main_loop_thread_safe_call_async(&notify_train_done, data);
+  return NULL;
+}
+
+static void *infer_(void *data) {
+  int status = ML_ERROR_NONE;
+  appdata_s *ad = (appdata_s *)data;
+
+  status = data_run_inference(ad);
+  if (status != ML_ERROR_NONE) {
+    LOG_E("inference process failed %d", status);
+    return NULL;
+  }
+
+  ecore_main_loop_thread_safe_call_async(view_update_guess, data);
 
   return NULL;
 }
@@ -179,13 +193,26 @@ void presenter_on_canvas_submit_inference(void *data, Evas_Object *obj,
                                           const char *emission,
                                           const char *source) {
   appdata_s *ad = (appdata_s *)data;
-  /** appdata handling NYI */
-  data_run_inference(ad);
+  pthread_t infer_thread;
+  int status = 0;
 
   ad->tries = 0;
   elm_naviframe_item_pop(ad->naviframe);
-  if (routes_to_(ad, "test_result") != 0)
+  if (routes_to_(ad, "test_result") != 0) {
+    LOG_E("routing to train thread failed");
     return;
+  }
+
+  status = pthread_create(&infer_thread, NULL, infer_, data);
+  if (status != 0) {
+    LOG_E("creating pthread failed %s", strerror(errno));
+    return;
+  }
+  status = pthread_detach(infer_thread);
+  if (status < 0) {
+    LOG_E("detaching reading thread failed %s", strerror(errno));
+    pthread_cancel(infer_thread);
+  }
 }
 
 void presenter_on_canvas_submit_training(void *data, Evas_Object *obj,
@@ -194,12 +221,6 @@ void presenter_on_canvas_submit_training(void *data, Evas_Object *obj,
   appdata_s *ad = (appdata_s *)data;
   int status = APP_ERROR_NONE;
 
-  status = data_update_label(ad);
-  if (status != APP_ERROR_NONE) {
-    LOG_E("setting draw label failed");
-    return;
-  }
-
   status = data_extract_feature(ad);
   if (status != APP_ERROR_NONE) {
     LOG_E("feature extraction failed");
@@ -227,6 +248,13 @@ void presenter_on_canvas_submit_training(void *data, Evas_Object *obj,
 
   /// prepare next canvas
   ad->tries++;
+
+  status = data_update_label(ad);
+  if (status != APP_ERROR_NONE) {
+    LOG_E("setting draw label failed");
+    return;
+  }
+
   view_set_canvas_clean(ad);
 }
 
index 5423125b72bf8135f16e87d477046e34184129cd..cf1598dea8aaff13fea1490957e1ecc44d03c83f 100644 (file)
@@ -237,27 +237,20 @@ static void on_canvas_exit_(void *data, Evas *e, Evas_Object *obj,
 
 void view_set_canvas_clean(appdata_s *ad) {
   char buf[256];
-  char emoji[5];
-
-  /// setting draw label and text
-  switch (ad->label) {
-  case LABEL_UNSET:
-    strcpy(emoji, "❓");
-    break;
-  case LABEL_SMILE:
-    strcpy(emoji, "😊");
-    break;
-  case LABEL_FROWN:
-    strcpy(emoji, "😢");
-    break;
-  default:
-    LOG_E("unreachable code");
-    return;
+  char *emoji;
+
+  int status = util_get_emoji(ad->label, &emoji);
+  if (status != APP_ERROR_NONE) {
+    LOG_E("getting emoji failed %d", status);
+    return status;
   }
+
   sprintf(buf, "draw for %s [%d/%d]", emoji, ad->tries + 1, MAX_TRIES);
   elm_object_part_text_set(ad->layout, "draw/title", buf);
   elm_object_part_text_set(ad->layout, "draw/label", emoji);
 
+  free(emoji);
+
   /// clear cairo surface
   cairo_set_source_rgba(ad->cr, 0.3, 0.3, 0.3, 0.2);
   cairo_set_operator(ad->cr, CAIRO_OPERATOR_SOURCE);
@@ -387,3 +380,21 @@ void view_update_result_cb(void *data, void *buffer, unsigned int nbytes) {
   snprintf(tmp, 255, "Loss: %.2f", result.train_loss);
   elm_object_part_text_set(ad->layout, "train_progress/loss", tmp);
 }
+
+void view_update_guess(void *data) {
+  appdata_s *ad = (appdata_s *)data;
+  char *emoji;
+  int status = util_get_emoji(ad->label, &emoji);
+  if (status != APP_ERROR_NONE) {
+    LOG_E("error getting emoji, reason: %d", status);
+    return status;
+  }
+
+  LOG_E("%s", emoji);
+  elm_object_part_text_set(ad->layout, "test_result/title",
+                           "guess successfully done");
+  elm_object_part_text_set(ad->layout, "test_result/label", emoji);
+  free(emoji);
+
+  return status;
+}