Use xxd -i to replace iree_c_embed_data in iree_model_input

Use "xxd -i" to replace iree_c_embed_data in iree_model_input. As a result, malloc and memcpy
on input buffers can be avoided. This also enable a future scenario of
using sensor inputs.

Change-Id: Ia378f21bc48cd2341f9b181ea627d7123e5fb01e
diff --git a/cmake/iree_model_input.cmake b/cmake/iree_model_input.cmake
index 7be9e35..60bf53b 100644
--- a/cmake/iree_model_input.cmake
+++ b/cmake/iree_model_input.cmake
@@ -51,7 +51,7 @@
   endif()
 
   set(_GEN_INPUT_SCRIPT "${CMAKE_SOURCE_DIR}/build_tools/gen_mlmodel_input.py")
-  set(_OUTPUT_BINARY ${_RULE_NAME}.bin)
+  set(_OUTPUT_BINARY ${_RULE_NAME})
   set(_ARGS)
   list(APPEND _ARGS "--i=${_INPUT_FILENAME}")
   list(APPEND _ARGS "--o=${_OUTPUT_BINARY}")
@@ -63,26 +63,54 @@
     list(APPEND _ARGS "--q")
   endif()
 
+  # Replace dependencies passed by ::name with iree::package::name
+  iree_package_ns(_PACKAGE_NS)
+  list(TRANSFORM _RULE_DEPS REPLACE "^::" "${_PACKAGE_NS}::")
+
+  # Prefix the library with the package name, so we get: iree_package_name.
+  iree_package_name(_PACKAGE_NAME)
+
+  set(_RULE_C_NAME "${_RULE_NAME}_c")
+  set(_LIB_NAME "${_PACKAGE_NAME}_${_RULE_C_NAME}")
+  set(_GEN_TARGET "${_LIB_NAME}_gen")
+  set(_H_FILE_NAME ${_RULE_C_NAME}.h)
+
   add_custom_command(
     OUTPUT
       ${_OUTPUT_BINARY}
+      ${_H_FILE_NAME}
     COMMAND
       ${_GEN_INPUT_SCRIPT} ${_ARGS}
+    COMMAND
+      xxd -i ${_OUTPUT_BINARY} > ${_H_FILE_NAME}
     DEPENDS
       ${_GEN_INPUT_SCRIPT}
       ${_INPUT_FILENAME}
   )
 
-  iree_c_embed_data(
-    NAME
-      "${_RULE_NAME}_c"
-    GENERATED_SRCS
-      "${_OUTPUT_BINARY}"
-    C_FILE_OUTPUT
-      "${_RULE_NAME}_c.c"
-    H_FILE_OUTPUT
-      "${_RULE_NAME}_c.h"
-    FLATTEN
-    PUBLIC
+  add_custom_target(
+    ${_GEN_TARGET}
+    DEPENDS
+      "${_H_FILE_NAME}"
   )
+
+  add_library(${_LIB_NAME}
+  ${_H_FILE_NAME}
+ )
+ add_dependencies(${_LIB_NAME} ${_GEN_TARGET})
+
+ SET_TARGET_PROPERTIES(
+   ${_LIB_NAME}
+   PROPERTIES
+   LINKER_LANGUAGE C
+ )
+
+ # Alias the iree_package_name library to iree::package::name.
+ # This lets us more clearly map to Bazel and makes it possible to
+ # disambiguate the underscores in paths vs. the separators.
+ add_library(${_PACKAGE_NS}::${_RULE_C_NAME} ALIAS ${_LIB_NAME})
+ iree_package_dir(_PACKAGE_DIR)
+ if(${_RULE_C_NAME} STREQUAL ${_PACKAGE_DIR})
+   add_library(${_PACKAGE_NS} ALIAS ${_LIB_NAME})
+ endif()
 endfunction()
diff --git a/samples/float_model/mnist.c b/samples/float_model/mnist.c
index 98bfbbb..5c7e874 100644
--- a/samples/float_model/mnist.c
+++ b/samples/float_model/mnist.c
@@ -36,11 +36,12 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
-  iree_status_t result = alloc_input_buffer(model, buffer);
-  const struct iree_file_toc_t *input_file_toc = mnist_input_c_create();
-  memcpy(*buffer, input_file_toc->data, input_file_toc->size);
-  return result;
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      mnist_input, model->input_size_bytes[0] * model->input_length[0]);
+  return iree_ok_status();
 }
 
 iree_status_t process_output(const MlModel *model,
diff --git a/samples/float_model/mobilenet_v1.c b/samples/float_model/mobilenet_v1.c
index a0163f5..4b610fd 100644
--- a/samples/float_model/mobilenet_v1.c
+++ b/samples/float_model/mobilenet_v1.c
@@ -36,11 +36,11 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
-  iree_status_t result = alloc_input_buffer(model, buffer);
-  const struct iree_file_toc_t *input_file_toc = mobilenet_input_c_create();
-  memcpy(*buffer, input_file_toc->data, input_file_toc->size);
-  return result;
+iree_status_t load_input_data(const MlModel *model, void **buffer, iree_byte_span_t **byte_span) {
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(mobilenet_input, model->input_size_bytes[0] *
+                                                  model->input_length[0]);
+  return iree_ok_status();
 }
 
 iree_status_t process_output(const MlModel *model,
diff --git a/samples/quant_model/barcode.c b/samples/quant_model/barcode.c
index 105c6da..d70733c 100644
--- a/samples/quant_model/barcode.c
+++ b/samples/quant_model/barcode.c
@@ -34,7 +34,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(768954);
@@ -43,6 +44,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/quant_model/daredevil.c b/samples/quant_model/daredevil.c
index c20447c..d4cb0ac 100644
--- a/samples/quant_model/daredevil.c
+++ b/samples/quant_model/daredevil.c
@@ -32,7 +32,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(3689964);
@@ -41,6 +42,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/quant_model/fssd_25_8bit_v2.c b/samples/quant_model/fssd_25_8bit_v2.c
index be979db..4070c81 100644
--- a/samples/quant_model/fssd_25_8bit_v2.c
+++ b/samples/quant_model/fssd_25_8bit_v2.c
@@ -33,7 +33,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(11111111);
@@ -42,6 +43,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/quant_model/mobilenet_v1.c b/samples/quant_model/mobilenet_v1.c
index f55232d..5640c5e 100644
--- a/samples/quant_model/mobilenet_v1.c
+++ b/samples/quant_model/mobilenet_v1.c
@@ -36,12 +36,13 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
-  iree_status_t result = alloc_input_buffer(model, buffer);
-  const struct iree_file_toc_t *input_file_toc =
-      mobilenet_quant_input_c_create();
-  memcpy(*buffer, input_file_toc->data, input_file_toc->size);
-  return result;
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] =
+      iree_make_byte_span(mobilenet_quant_input,
+                          model->input_size_bytes[0] * model->input_length[0]);
+  return iree_ok_status();
 }
 
 iree_status_t process_output(const MlModel *model,
diff --git a/samples/quant_model/mobilenet_v2.c b/samples/quant_model/mobilenet_v2.c
index 612ce65..990d724 100644
--- a/samples/quant_model/mobilenet_v2.c
+++ b/samples/quant_model/mobilenet_v2.c
@@ -32,7 +32,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(33333333);
@@ -41,6 +42,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/quant_model/person_detection.c b/samples/quant_model/person_detection.c
index 0f8e4ea..379eb0f 100644
--- a/samples/quant_model/person_detection.c
+++ b/samples/quant_model/person_detection.c
@@ -36,12 +36,13 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
-  iree_status_t result = alloc_input_buffer(model, buffer);
-  const struct iree_file_toc_t *input_file_toc =
-      person_detection_quant_input_c_create();
-  memcpy(*buffer, input_file_toc->data, input_file_toc->size);
-  return result;
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] =
+      iree_make_byte_span(person_detection_quant_input,
+                          model->input_size_bytes[0] * model->input_length[0]);
+  return iree_ok_status();
 }
 
 iree_status_t process_output(const MlModel *model,
diff --git a/samples/quant_model/scenenet_v2.c b/samples/quant_model/scenenet_v2.c
index 931c389..da680f7 100644
--- a/samples/quant_model/scenenet_v2.c
+++ b/samples/quant_model/scenenet_v2.c
@@ -32,7 +32,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(55555555);
@@ -41,6 +42,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/quant_model/semantic_lift.c b/samples/quant_model/semantic_lift.c
index 2ce1e95..973bc0b 100644
--- a/samples/quant_model/semantic_lift.c
+++ b/samples/quant_model/semantic_lift.c
@@ -32,7 +32,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(66666666);
@@ -41,6 +42,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/quant_model/voice_commands.c b/samples/quant_model/voice_commands.c
index 4fdbbee..18b06a7 100644
--- a/samples/quant_model/voice_commands.c
+++ b/samples/quant_model/voice_commands.c
@@ -32,7 +32,8 @@
                                    module_file_toc->size);
 }
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial value
   srand(77777777);
@@ -41,6 +42,9 @@
       ((uint8_t *)*buffer)[i] = (uint8_t)rand();
     }
   }
+  byte_span[0] = malloc(sizeof(iree_byte_span_t));
+  *byte_span[0] = iree_make_byte_span(
+      buffer[0], model->input_size_bytes[0] * model->input_length[0]);
   return result;
 }
 
diff --git a/samples/simple_vec_mul/float_vec.c b/samples/simple_vec_mul/float_vec.c
index 15c50e2..1d4a2d1 100644
--- a/samples/simple_vec_mul/float_vec.c
+++ b/samples/simple_vec_mul/float_vec.c
@@ -46,7 +46,8 @@
 }
 #endif
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial values
   // arg0 = 0, 1/4, 1/2, 3/4... 1023/4
@@ -57,6 +58,11 @@
       ((float *)buffer[1])[i] = i / 2.0f;
     }
   }
+  for (int i = 0; i < model->num_input; ++i) {
+    byte_span[i] = malloc(sizeof(iree_byte_span_t));
+    *byte_span[i] = iree_make_byte_span(
+        buffer[i], model->input_size_bytes[i] * model->input_length[i]);
+  }
   return result;
 }
 
diff --git a/samples/simple_vec_mul/int_vec.c b/samples/simple_vec_mul/int_vec.c
index 6abf697..7a78c81 100644
--- a/samples/simple_vec_mul/int_vec.c
+++ b/samples/simple_vec_mul/int_vec.c
@@ -46,7 +46,8 @@
 }
 #endif
 
-iree_status_t load_input_data(const MlModel *model, void **buffer) {
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span) {
   iree_status_t result = alloc_input_buffer(model, buffer);
   // Populate initial values
   // arg0 = 0, 0, 1, 1,..., 511
@@ -57,6 +58,11 @@
       ((int32_t *)buffer[1])[i] = i;
     }
   }
+  for (int i = 0; i < model->num_input; ++i) {
+    byte_span[i] = malloc(sizeof(iree_byte_span_t));
+    *byte_span[i] = iree_make_byte_span(
+        buffer[i], model->input_size_bytes[i] * model->input_length[i]);
+  }
   return result;
 }
 
diff --git a/samples/util/model_api.h b/samples/util/model_api.h
index c5671c7..a996bcb 100644
--- a/samples/util/model_api.h
+++ b/samples/util/model_api.h
@@ -47,7 +47,8 @@
 // For each ML workload, based on the model configuration, allocate the buffer
 // and prepare the data. It can be loaded from a embedded image binary, a
 // randomly generated stream, or a pointer from the sensor/ISP output.
-iree_status_t load_input_data(const MlModel *model, void **buffer);
+iree_status_t load_input_data(const MlModel *model, void **buffer,
+                              iree_byte_span_t **byte_span);
 
 // Process the ML execution output into the final data to be sent to the
 // host. The final format is model dependent, so the address and size
diff --git a/samples/util/util.c b/samples/util/util.c
index b347358..f629dce 100644
--- a/samples/util/util.c
+++ b/samples/util/util.c
@@ -34,7 +34,8 @@
 
   // Prepare the input buffer, and populate the initial value.
   // The input buffer must be released by the caller.
-  result = load_input_data(model, arg_buffers);
+  iree_byte_span_t *byte_span[MAX_MODEL_INPUT_NUM] = {NULL};
+  result = load_input_data(model, arg_buffers, byte_span);
 
   // Wrap buffers in shaped buffer views.
   // The buffers can be mapped on the CPU and that can also be used
@@ -48,11 +49,12 @@
           iree_hal_device_allocator(device), model->input_shape[i],
           model->num_input_dim[i], model->hal_element_type,
           IREE_HAL_ENCODING_TYPE_DENSE_ROW_MAJOR, input_memory_type,
-          IREE_HAL_MEMORY_ACCESS_READ, IREE_HAL_BUFFER_USAGE_ALL,
-          iree_make_byte_span(arg_buffers[i], model->input_size_bytes[i] *
-                                                  model->input_length[i]),
+          IREE_HAL_MEMORY_ACCESS_READ, IREE_HAL_BUFFER_USAGE_ALL, *byte_span[i],
           iree_allocator_null(), &(arg_buffer_views[i]));
     }
+    if (byte_span[i] != NULL) {
+      free(byte_span[i]);
+    }
   }
   return result;
 }