Move HPS model related stuffs to public folder

Move HPS model related stuffs from internal to public folder.

Change-Id: I94ee96f7c86f1bc183f4425a4043c693a7b6988d
diff --git a/README.md b/README.md
index 2bc39f3..7684d92 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@
 
 Mobilenet V2 quantized model from https://tfhub.dev/tensorflow/lite-model/mobilenet_v2_1.0_224_quantized/1/default/1?lite-format=tflite
 
+### hps_quant.tflite
+
+HPS (Human Presence Sensor) non-tiled quantized model from https://chromium.googlesource.com/chromiumos/platform/hps-firmware/+/6cdea6d1158a8cd3238b8ae4f744fdb494779c80/models/shared.tflite
+
 ## Visualize the model
 
 For tflite models, use the [web-based visualization tool](https://lutzroeder.github.io/netron/) to
diff --git a/quant_models/CMakeLists.txt b/quant_models/CMakeLists.txt
index 0281dd9..50ca35a 100644
--- a/quant_models/CMakeLists.txt
+++ b/quant_models/CMakeLists.txt
@@ -11,6 +11,19 @@
 
 springbok_modules(
   NAME
+    hps
+  SRC
+    "hps_quant.tflite"
+  C_IDENTIFIER
+    "quant_models_hps"
+  FLAGS
+    "-iree-input-type=tosa"
+  RVV_OFF
+  PUBLIC
+)
+
+springbok_modules(
+  NAME
     mobilenet_v1
   SRC
     "mobilenet_v1_0.25_224_quant.tflite"
@@ -55,6 +68,19 @@
 # Binaries to execute the IREE model input
 # ------------------------------------------------------------------------------
 
+foreach(N 0 1 2 3 4 5 6)
+  iree_model_input(
+    NAME
+      hps_${N}_quant_input
+    SHAPE
+      "1, 240, 320, 1"
+    SRC
+      "$ENV{ROOTDIR}/ml/ml-models-public/test_data/hps_${N}.jpg"
+    QUANT
+    SIGNED
+  )
+endforeach()
+
 iree_model_input(
   NAME
     mobilenet_quant_input
@@ -88,6 +114,49 @@
 #
 # to increase it.
 
+foreach(N 0 1 2 3 4 5 6)
+iree_cc_binary(
+  NAME
+    hps_${N}_bytecode_static
+  SRCS
+    "iree_exec/hps.c"
+  DEPS
+    ::hps_${N}_quant_input_c
+    ::hps_bytecode_module_static_c
+    ::hps_bytecode_module_static_lib
+    iree::vm::bytecode_module
+    model_util::util_static
+  COPTS
+    "-DHPS_IDX=${N}"
+  LINKOPTS
+    "LINKER:--defsym=__stack_size__=200k"
+    # TODO(b/241297921): determine HPS heap size
+    "LINKER:--defsym=__heap_size__=5M"
+)
+
+springbok_test(
+  NAME
+    hps_${N}_emitc_static
+  SRCS
+    "iree_exec/hps.c"
+  DEPS
+    ::hps_${N}_quant_input_c
+    ::hps_c_module_static_emitc
+    ::hps_c_module_static_lib
+    model_util::util_static
+  LINKOPTS
+    "LINKER:--defsym=__stack_size__=200k"
+    # TODO(b/241297921): determine HPS heap size
+    "LINKER:--defsym=__heap_size__=5M"
+  COPTS
+    "-DHPS_IDX=${N}"
+    "-DBUILD_EMITC"
+  TESTFILES
+    "iree_exec/hps_test.run"
+    "iree_exec/hps_${N}_test.filecheck"
+)
+endforeach()
+
 iree_cc_binary(
   NAME
     mobilenet_v1_bytecode_static
diff --git a/quant_models/hps_quant.tflite b/quant_models/hps_quant.tflite
new file mode 100644
index 0000000..71457ad
--- /dev/null
+++ b/quant_models/hps_quant.tflite
Binary files differ
diff --git a/quant_models/iree_exec/hps.c b/quant_models/iree_exec/hps.c
new file mode 100644
index 0000000..5537c29
--- /dev/null
+++ b/quant_models/iree_exec/hps.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Human Presence Sensor Model
+
+#include "hps.h"
+
+#include <springbok.h>
+
+#include "iree/base/api.h"
+#include "iree/hal/api.h"
+#include "model_util/util.h"
+
+#if HPS_IDX == 0
+#include "hps_0_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_0_quant_input
+#elif HPS_IDX == 2
+#include "hps_2_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_2_quant_input
+#elif HPS_IDX == 3
+#include "hps_3_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_3_quant_input
+#elif HPS_IDX == 4
+#include "hps_4_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_4_quant_input
+#elif HPS_IDX == 5
+#include "hps_5_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_5_quant_input
+#elif HPS_IDX == 6
+#include "hps_6_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_6_quant_input
+#else
+#include "hps_1_quant_input_c.h"
+#define HPS_QUANT_INPUT hps_1_quant_input
+#endif
+
+// Compiled module embedded here to avoid file IO:
+#if !defined(BUILD_EMITC)
+#include "hps_bytecode_module_static.h"
+#include "hps_bytecode_module_static_c.h"
+#else
+#include "hps_c_module_static_c.h"
+#include "hps_c_module_static_emitc.h"
+#endif
+
+__attribute__((section(".model_output"))) HpsOutput score;
+
+iree_status_t create_module(iree_vm_instance_t *instance,
+                            iree_vm_module_t **module) {
+#if !defined(BUILD_EMITC)
+  const struct iree_file_toc_t *module_file_toc =
+      quant_models_hps_bytecode_module_static_create();
+  return iree_vm_bytecode_module_create(
+      instance,
+      iree_make_const_byte_span(module_file_toc->data, module_file_toc->size),
+      iree_allocator_null(), iree_allocator_system(), module);
+#else
+  return module_create(instance, iree_allocator_system(), module);
+#endif
+}
+
+iree_hal_executable_library_query_fn_t library_query(void) {
+#if !defined(BUILD_EMITC)
+  return &hps_bytecode_module_static_linked_llvm_cpu_library_query;
+#else
+  return &hps_c_module_static_linked_llvm_cpu_library_query;
+#endif
+}
+
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_const_byte_span_t **byte_span) {
+  byte_span[0] = malloc(sizeof(iree_const_byte_span_t));
+  *byte_span[0] = iree_make_const_byte_span(
+      HPS_QUANT_INPUT, model->input_size_bytes[0] * model->input_length[0]);
+  return iree_ok_status();
+}
+
+iree_status_t process_output(const MlModel *model,
+                             iree_hal_buffer_mapping_t *buffers,
+                             uint32_t *output_length) {
+  iree_status_t result = iree_ok_status();
+  int8_t *data = (int8_t *)buffers[0].contents.data;
+  score.score_0 = data[0];
+  score.score_1 = data[1];
+
+  LOG_INFO("Score 0: %d, Score 1: %d", score.score_0, score.score_1);
+
+  *output_length = sizeof(score);
+  return result;
+}
diff --git a/quant_models/iree_exec/hps.h b/quant_models/iree_exec/hps.h
new file mode 100644
index 0000000..0a9d0b7
--- /dev/null
+++ b/quant_models/iree_exec/hps.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef QUANT_MODELS_IREE_EXEC_HPS_H_
+#define QUANT_MODELS_IREE_EXEC_HPS_H_
+
+#include <stdint.h>
+
+#include "model_util/util.h"
+
+typedef struct {
+  int8_t score_0;
+  int8_t score_1;
+} HpsOutput;
+
+const MlModel kModel = {
+    .num_input = 1,
+    .num_input_dim = {4},
+    .input_shape = {{1, 240, 320, 1}},
+    .input_length = {240 * 320 * 1},
+    .input_size_bytes = {sizeof(int8_t)},
+    .num_output = 1,
+    .output_length = {2},
+    .output_size_bytes = sizeof(int8_t),
+    .hal_element_type = IREE_HAL_ELEMENT_TYPE_SINT_8,
+    .entry_func = "module.main",
+    .model_name = "hps_quant",
+};
+
+#endif  // QUANT_MODELS_IREE_EXEC_HPS_H_
diff --git a/quant_models/iree_exec/hps_0_test.filecheck b/quant_models/iree_exec/hps_0_test.filecheck
new file mode 100644
index 0000000..bdb087d
--- /dev/null
+++ b/quant_models/iree_exec/hps_0_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: -118, Score 1: -128
diff --git a/quant_models/iree_exec/hps_1_test.filecheck b/quant_models/iree_exec/hps_1_test.filecheck
new file mode 100644
index 0000000..a934a24
--- /dev/null
+++ b/quant_models/iree_exec/hps_1_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: 127, Score 1: -128
diff --git a/quant_models/iree_exec/hps_2_test.filecheck b/quant_models/iree_exec/hps_2_test.filecheck
new file mode 100644
index 0000000..d5c0e12
--- /dev/null
+++ b/quant_models/iree_exec/hps_2_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: 127, Score 1: 127
diff --git a/quant_models/iree_exec/hps_3_test.filecheck b/quant_models/iree_exec/hps_3_test.filecheck
new file mode 100644
index 0000000..ac3ec09
--- /dev/null
+++ b/quant_models/iree_exec/hps_3_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: -115, Score 1: -128
diff --git a/quant_models/iree_exec/hps_4_test.filecheck b/quant_models/iree_exec/hps_4_test.filecheck
new file mode 100644
index 0000000..269b27c
--- /dev/null
+++ b/quant_models/iree_exec/hps_4_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: -97, Score 1: -128
diff --git a/quant_models/iree_exec/hps_5_test.filecheck b/quant_models/iree_exec/hps_5_test.filecheck
new file mode 100644
index 0000000..a934a24
--- /dev/null
+++ b/quant_models/iree_exec/hps_5_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: 127, Score 1: -128
diff --git a/quant_models/iree_exec/hps_6_test.filecheck b/quant_models/iree_exec/hps_6_test.filecheck
new file mode 100644
index 0000000..9babf4a
--- /dev/null
+++ b/quant_models/iree_exec/hps_6_test.filecheck
@@ -0,0 +1 @@
+// CHECK: Score 0: 127, Score 1: -115
diff --git a/quant_models/iree_exec/hps_test.run b/quant_models/iree_exec/hps_test.run
new file mode 100644
index 0000000..7565300
--- /dev/null
+++ b/quant_models/iree_exec/hps_test.run
@@ -0,0 +1,41 @@
+// RUN: ${TEST_RUNNER_CMD} %S/hps_0_emitc_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_0_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_0_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_0_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_1_emitc_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_1_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_1_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_1_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_2_emitc_static 2>&1 | tee %t
+// cat %t | FileCheck %S/hps_2_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_2_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_2_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_3_emitc_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_3_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_3_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_3_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_4_emitc_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_4_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_4_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_4_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_5_emitc_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_5_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_5_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_5_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_6_emitc_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_6_test.filecheck
+
+// RUN: ${TEST_RUNNER_CMD} %S/hps_6_bytecode_static 2>&1 | tee %t
+// RUN: cat %t | FileCheck %S/hps_6_test.filecheck