Add shodan float-point models to build/run on springbok Add shodan float-point ML models to build/run on springbok emulator. Currently all models can be compiled and run on qemu linux emulator. But not all models can run on qemu springbok with or without RVV, due to a known issue on the upstream: - Large HAL buffer: b/196910893 Change-Id: I4f28e20f4c4fce5c64b018798e8d74265256ad11
diff --git a/samples/float_model_embedding/CMakeLists.txt b/samples/float_model_embedding/CMakeLists.txt new file mode 100644 index 0000000..7e64777 --- /dev/null +++ b/samples/float_model_embedding/CMakeLists.txt
@@ -0,0 +1,255 @@ +#------------------------------------------------------------------------------- +# Build the mlir bytecode modules with iree-translate. Note the last two flags +# and "+experimental-v" are for RVV support. +#------------------------------------------------------------------------------- + +if(NOT ${BUILD_WITH_SPRINGBOK}) + springbok_bytecode_module( + NAME + mobilenet_v2_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/mobilenet_v2_1.0_224_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_mobilenet_v2_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC + ) + + springbok_bytecode_module( + NAME + scenenet_v2_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/scenenet_v2_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_scenenet_v2_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC + ) +endif() + +springbok_bytecode_module( + NAME + barcode_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/barcode_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_barcode_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +springbok_bytecode_module( + NAME + daredevil_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/daredevil_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_daredevil_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +springbok_bytecode_module( + NAME + fssd_25_8bit_v2_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/fssd_25_8bit_v2_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_fssd_25_8bit_v2_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +springbok_bytecode_module( + NAME + mobilenet_v1_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/mobilenet_v1_0.25_224_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_mobilenet_v1_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +springbok_bytecode_module( + NAME + person_detection_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/person_detection_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_person_detection_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +springbok_bytecode_module( + NAME + semantic_lift_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/semantic_lift_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_semantic_lift_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +springbok_bytecode_module( + NAME + voice_commands_bytecode_module_dylib + SRC + "$ENV{ROOTDIR}/ml/ml-models/float_models/voice_commands_float.tflite" + C_IDENTIFIER + "samples_float_model_embedding_voice_commands_bytecode_module_dylib" + FLAGS + "-iree-input-type=tosa" + "-riscv-v-vector-bits-min=512" + "-riscv-v-fixed-length-vector-lmul-max=8" + "-riscv-v-fixed-length-vector-elen-max=32" + PUBLIC +) + +#------------------------------------------------------------------------------- +# Binaries to execute the MLIR bytecode modules +#------------------------------------------------------------------------------- + + +# If the program requires a larger stack size, add +# +# LINKOPTS +# "LINKER:--defsym=__stack_size__=<new stack size>" +# +# to increase it. + +if(NOT ${BUILD_WITH_SPRINGBOK}) + iree_cc_binary( + NAME + mobilenet_v2_embedded_sync + SRCS + "mobilenet_v2.c" + DEPS + ::mobilenet_v2_bytecode_module_dylib_c + samples::util::util + ) + + iree_cc_binary( + NAME + scenenet_v2_embedded_sync + SRCS + "scenenet_v2.c" + DEPS + ::scenenet_v2_bytecode_module_dylib_c + samples::util::util + ) +endif() + +iree_cc_binary( + NAME + barcode_embedded_sync + SRCS + "barcode.c" + DEPS + ::barcode_bytecode_module_dylib_c + samples::util::util + LINKOPTS + "LINKER:--defsym=__stack_size__=100k" +) + +iree_cc_binary( + NAME + daredevil_embedded_sync + SRCS + "daredevil.c" + DEPS + ::daredevil_bytecode_module_dylib_c + samples::util::util + LINKOPTS + "LINKER:--defsym=__stack_size__=100k" +) + +iree_cc_binary( + NAME + fssd_25_8bit_v2_embedded_sync + SRCS + "fssd_25_8bit_v2.c" + DEPS + ::fssd_25_8bit_v2_bytecode_module_dylib_c + samples::util::util + LINKOPTS + "LINKER:--defsym=__stack_size__=100k" +) + +iree_cc_binary( + NAME + mobilenet_v1_embedded_sync + SRCS + "mobilenet_v1.c" + DEPS + ::mobilenet_v1_bytecode_module_dylib_c + samples::util::util + LINKOPTS + "LINKER:--defsym=__stack_size__=100k" +) + +iree_cc_binary( + NAME + person_detection_embedded_sync + SRCS + "person_detection.c" + DEPS + ::person_detection_bytecode_module_dylib_c + samples::util::util + LINKOPTS + "LINKER:--defsym=__stack_size__=100k" +) + +iree_cc_binary( + NAME + semantic_lift_embedded_sync + SRCS + "semantic_lift.c" + DEPS + ::semantic_lift_bytecode_module_dylib_c + samples::util::util +) + +iree_cc_binary( + NAME + voice_commands_embedded_sync + SRCS + "voice_commands.c" + DEPS + ::voice_commands_bytecode_module_dylib_c + samples::util::util +)
diff --git a/samples/float_model_embedding/barcode.c b/samples/float_model_embedding/barcode.c new file mode 100644 index 0000000..3d047f5 --- /dev/null +++ b/samples/float_model_embedding/barcode.c
@@ -0,0 +1,57 @@ +// Barcode float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/barcode_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 320, 320, 1}, + .input_length = 320 * 320 * 1, + .input_size_bytes = sizeof(float), + .num_output = 12, + .output_length = {20 * 20 * 36, 20 * 20 * 9, 10 * 10 * 72, 10 * 10 * 18, + 5 * 5 * 72, 5 * 5 * 18, 3 * 3 * 72, 3 * 3 * 18, + 2 * 2 * 72, 2 * 2 * 18, 72, 18}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "barcode_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_barcode_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(768954); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/daredevil.c b/samples/float_model_embedding/daredevil.c new file mode 100644 index 0000000..b74e425 --- /dev/null +++ b/samples/float_model_embedding/daredevil.c
@@ -0,0 +1,55 @@ +// Daredevil float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/daredevil_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 3, + .input_shape = {1, 96, 64}, + .input_length = 96 * 64, + .input_size_bytes = sizeof(float), + .num_output = 1, + .output_length = {527}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "daredevil_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_daredevil_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(3689964); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/fssd_25_8bit_v2.c b/samples/float_model_embedding/fssd_25_8bit_v2.c new file mode 100644 index 0000000..e7f660a --- /dev/null +++ b/samples/float_model_embedding/fssd_25_8bit_v2.c
@@ -0,0 +1,55 @@ +// Fssd_25_8bit_v2 float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/fssd_25_8bit_v2_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 320, 320, 3}, + .input_length = 320 * 320 * 3, + .input_size_bytes = sizeof(float), + .num_output = 2, + .output_length = {1602, 1602 * 16}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "fssd_25_8bit_v2_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_fssd_25_8bit_v2_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(11111111); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/mobilenet_v1.c b/samples/float_model_embedding/mobilenet_v1.c new file mode 100644 index 0000000..fa15389 --- /dev/null +++ b/samples/float_model_embedding/mobilenet_v1.c
@@ -0,0 +1,55 @@ +// Mobilenet_v1_0.25_224 float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/mobilenet_v1_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 224, 224, 3}, + .input_length = 224 * 224 * 3, + .input_size_bytes = sizeof(float), + .num_output = 1, + .output_length = {1001}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "mobilenet_v1_0.25_224_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_mobilenet_v1_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(33333333); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/mobilenet_v2.c b/samples/float_model_embedding/mobilenet_v2.c new file mode 100644 index 0000000..7d139ef --- /dev/null +++ b/samples/float_model_embedding/mobilenet_v2.c
@@ -0,0 +1,55 @@ +// Mobilenet_v2_1.0_224 float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/mobilenet_v2_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 224, 224, 3}, + .input_length = 224 * 224 * 3, + .input_size_bytes = sizeof(float), + .num_output = 1, + .output_length = {1001}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "mobilenet_v2_1.0_224_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_mobilenet_v2_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(33333333); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/person_detection.c b/samples/float_model_embedding/person_detection.c new file mode 100644 index 0000000..ad945e1 --- /dev/null +++ b/samples/float_model_embedding/person_detection.c
@@ -0,0 +1,55 @@ +// Person_detection float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/person_detection_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 96, 96, 1}, + .input_length = 96 * 96 * 1, + .input_size_bytes = sizeof(float), + .num_output = 1, + .output_length = {2}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "person_detection_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_person_detection_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(44444444); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/scenenet_v2.c b/samples/float_model_embedding/scenenet_v2.c new file mode 100644 index 0000000..1d6662d --- /dev/null +++ b/samples/float_model_embedding/scenenet_v2.c
@@ -0,0 +1,55 @@ +// Scenenet_v2 float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/scenenet_v2_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 192, 192, 3}, + .input_length = 192 * 192 * 3, + .input_size_bytes = sizeof(float), + .num_output = 1, + .output_length = {170}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "scenenet_v2_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_scenenet_v2_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(55555555); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/semantic_lift.c b/samples/float_model_embedding/semantic_lift.c new file mode 100644 index 0000000..c037f24 --- /dev/null +++ b/samples/float_model_embedding/semantic_lift.c
@@ -0,0 +1,55 @@ +// Semantic_lift float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/semantic_lift_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 4, + .input_shape = {1, 128, 128, 3}, + .input_length = 128 * 128 * 3, + .input_size_bytes = sizeof(float), + .num_output = 2, + .output_length = {2, 2}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "semantic_lift_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_semantic_lift_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(66666666); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/float_model_embedding/voice_commands.c b/samples/float_model_embedding/voice_commands.c new file mode 100644 index 0000000..29aa61e --- /dev/null +++ b/samples/float_model_embedding/voice_commands.c
@@ -0,0 +1,55 @@ +// Voice_commands float model +// MlModel struct initialization to include model I/O info. +// Bytecode loading, input/output processes. + +#include <springbok.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "samples/util/util.h" + +// Compiled module embedded here to avoid file IO: +#include "samples/float_model_embedding/voice_commands_bytecode_module_dylib_c.h" + +const MlModel kModel = { + .num_input_dim = 3, + .input_shape = {1, 198, 32}, + .input_length = 198 * 32, + .input_size_bytes = sizeof(float), + .num_output = 1, + .output_length = {63}, + .output_size_bytes = sizeof(float), + .hal_element_type = IREE_HAL_ELEMENT_TYPE_FLOAT_32, + .model_name = "voice_commands_float", +}; + +const iree_const_byte_span_t load_bytecode_module_data() { + const struct iree_file_toc_t *module_file_toc = + samples_float_model_embedding_voice_commands_bytecode_module_dylib_create(); + return iree_make_const_byte_span(module_file_toc->data, + module_file_toc->size); +} + +iree_status_t load_input_data(const MlModel *model, void **buffer) { + // Populate initial value + srand(77777777); + for (int i = 0; i < model->input_length; ++i) { + int x = rand(); + ((float *)*buffer)[i] = (float)x / (float)RAND_MAX; + } + return iree_ok_status(); +} + +iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output) { + iree_status_t result = iree_ok_status(); + if (index_output > model->num_output || + mapped_memory->contents.data_length / model->output_size_bytes != + model->output_length[index_output]) { + result = iree_make_status(IREE_STATUS_UNKNOWN, "output length mismatches"); + } + LOG_INFO("Output #%d data length: %d \n", index_output, + mapped_memory->contents.data_length / model->output_size_bytes); + return result; +}
diff --git a/samples/util/CMakeLists.txt b/samples/util/CMakeLists.txt new file mode 100644 index 0000000..b004f46 --- /dev/null +++ b/samples/util/CMakeLists.txt
@@ -0,0 +1,18 @@ +include_directories($ENV{ROOTDIR}/sw/vec/springbok/include) + +iree_cc_library( + NAME + util + SRCS + "util.c" + DEPS + iree::base + iree::hal + iree::hal::local + iree::hal::local::loaders::embedded_library_loader + iree::hal::local::sync_driver + iree::modules::hal + iree::vm + iree::vm::bytecode_module + samples::device::device_embedded_sync +)
diff --git a/samples/util/util.c b/samples/util/util.c new file mode 100644 index 0000000..e24684f --- /dev/null +++ b/samples/util/util.c
@@ -0,0 +1,190 @@ +// An example based on iree/samples/simple_embedding. + +#include <springbok.h> +#include <stdio.h> + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "iree/modules/hal/module.h" +#include "iree/vm/api.h" +#include "iree/vm/bytecode_module.h" +#include "samples/util/util.h" + +// A function to create the HAL device from the different backend targets. +// The HAL device is returned based on the implementation, and it must be +// released by the caller +extern iree_status_t create_sample_device(iree_hal_device_t **device); + +extern const iree_const_byte_span_t load_bytecode_module_data(); + +extern iree_status_t load_input_data(const MlModel *model, void **buffer); + +extern iree_status_t check_output_data(const MlModel *model, + iree_hal_buffer_mapping_t *mapped_memory, + int index_output); + +extern const MlModel kModel; + +// Prepare the input buffers and buffer_views based on the data type. They must +// be released by the caller. +static iree_status_t prepare_input_hal_buffer_views( + const MlModel *model, iree_hal_device_t *device, void **arg0_buffer, + iree_hal_buffer_view_t **arg0_buffer_view) { + iree_status_t result = iree_ok_status(); + *arg0_buffer = iree_aligned_alloc( + sizeof(uint32_t), model->input_size_bytes * model->input_length); + if (*arg0_buffer == NULL) { + result = iree_make_status(IREE_STATUS_RESOURCE_EXHAUSTED); + } + + // Populate initial value + load_input_data(model, arg0_buffer); + + // Wrap buffers in shaped buffer views. + // The buffers can be mapped on the CPU and that can also be used + // on the device. Not all devices support this, but the ones we have now do. + + iree_hal_memory_type_t input_memory_type = + IREE_HAL_MEMORY_TYPE_HOST_LOCAL | IREE_HAL_MEMORY_TYPE_DEVICE_VISIBLE; + + result = iree_hal_buffer_view_wrap_or_clone_heap_buffer( + iree_hal_device_allocator(device), model->input_shape, + model->num_input_dim, model->hal_element_type, input_memory_type, + IREE_HAL_ENCODING_TYPE_DENSE_ROW_MAJOR, IREE_HAL_MEMORY_ACCESS_READ, + IREE_HAL_BUFFER_USAGE_ALL, + iree_make_byte_span(*arg0_buffer, + model->input_size_bytes * model->input_length), + iree_allocator_null(), arg0_buffer_view); + return result; +} + +iree_status_t run(const MlModel *model) { + IREE_RETURN_IF_ERROR(iree_hal_module_register_types()); + + iree_vm_instance_t *instance = NULL; + iree_status_t result = + iree_vm_instance_create(iree_allocator_system(), &instance); + + iree_hal_device_t *device = NULL; + if (iree_status_is_ok(result)) { + result = create_sample_device(&device); + } + iree_vm_module_t *hal_module = NULL; + if (iree_status_is_ok(result)) { + result = + iree_hal_module_create(device, iree_allocator_system(), &hal_module); + } + // Load bytecode module from the embedded data. + const iree_const_byte_span_t module_data = load_bytecode_module_data(); + + iree_vm_module_t *bytecode_module = NULL; + if (iree_status_is_ok(result)) { + result = iree_vm_bytecode_module_create(module_data, iree_allocator_null(), + iree_allocator_system(), + &bytecode_module); + } + + // Allocate a context that will hold the module state across invocations. + iree_vm_context_t *context = NULL; + iree_vm_module_t *modules[] = {hal_module, bytecode_module}; + if (iree_status_is_ok(result)) { + result = iree_vm_context_create_with_modules( + instance, &modules[0], IREE_ARRAYSIZE(modules), iree_allocator_system(), + &context); + } + iree_vm_module_release(hal_module); + iree_vm_module_release(bytecode_module); + + // Lookup the entry point function. + // Note that we use the synchronous variant which operates on pure type/shape + // erased buffers. + const char kMainFunctionName[] = "module.main"; + iree_vm_function_t main_function; + if (iree_status_is_ok(result)) { + result = (iree_vm_context_resolve_function( + context, iree_make_cstring_view(kMainFunctionName), &main_function)); + } + + // Prepare the input buffers. + void *arg0_buffer = NULL; + iree_hal_buffer_view_t *arg0_buffer_view = NULL; + if (iree_status_is_ok(result)) { + result = prepare_input_hal_buffer_views(model, device, &arg0_buffer, + &arg0_buffer_view); + } + + // Setup call inputs with our buffers. + iree_vm_list_t *inputs = NULL; + if (iree_status_is_ok(result)) { + result = iree_vm_list_create( + /*element_type=*/NULL, + /*capacity=*/1, iree_allocator_system(), &inputs); + } + iree_vm_ref_t arg0_buffer_view_ref = + iree_hal_buffer_view_move_ref(arg0_buffer_view); + if (iree_status_is_ok(result)) { + result = iree_vm_list_push_ref_move(inputs, &arg0_buffer_view_ref); + } + + // Prepare outputs list to accept the results from the invocation. + // The output vm list is allocated statically. + iree_vm_list_t *outputs = NULL; + if (iree_status_is_ok(result)) { + result = iree_vm_list_create( + /*element_type=*/NULL, + /*capacity=*/1, iree_allocator_system(), &outputs); + } + + // Invoke the function. + if (iree_status_is_ok(result)) { + result = iree_vm_invoke(context, main_function, + /*policy=*/NULL, inputs, outputs, + iree_allocator_system()); + } + + for (int index_output = 0; index_output < model->num_output; index_output++) { + iree_hal_buffer_view_t *ret_buffer_view = NULL; + if (iree_status_is_ok(result)) { + // Get the result buffers from the invocation. + ret_buffer_view = (iree_hal_buffer_view_t *)iree_vm_list_get_ref_deref( + outputs, index_output, iree_hal_buffer_view_get_descriptor()); + if (ret_buffer_view == NULL) { + result = iree_make_status(IREE_STATUS_NOT_FOUND, + "can't find return buffer view"); + } + } + // Read back the results and ensure we got the right values. + iree_hal_buffer_mapping_t mapped_memory; + if (iree_status_is_ok(result)) { + result = iree_hal_buffer_map_range( + iree_hal_buffer_view_buffer(ret_buffer_view), + IREE_HAL_MEMORY_ACCESS_READ, 0, IREE_WHOLE_BUFFER, &mapped_memory); + } + if (iree_status_is_ok(result)) { + result = check_output_data(model, &mapped_memory, index_output); + iree_hal_buffer_unmap_range(&mapped_memory); + } + } + + iree_vm_list_release(inputs); + iree_vm_list_release(outputs); + iree_aligned_free(arg0_buffer); + iree_hal_device_release(device); + iree_vm_context_release(context); + iree_vm_instance_release(instance); + return result; +} + +int main() { + const MlModel *model_ptr = &kModel; + const iree_status_t result = run(model_ptr); + int ret = (int)iree_status_code(result); + if (!iree_status_is_ok(result)) { + iree_status_fprint(stderr, result); + iree_status_free(result); + } else { + LOG_INFO("%s finished successfully", model_ptr->model_name); + } + + return ret; +}
diff --git a/samples/util/util.h b/samples/util/util.h new file mode 100644 index 0000000..6cd2e38 --- /dev/null +++ b/samples/util/util.h
@@ -0,0 +1,25 @@ +#ifndef SW_VEC_IREE_SAMPLES_UTIL_H_ +#define SW_VEC_IREE_SAMPLES_UTIL_H_ + +#include "iree/base/api.h" +#include "iree/hal/api.h" +#include "iree/modules/hal/module.h" +#include "iree/vm/api.h" +#include "iree/vm/bytecode_module.h" + +#define MAX_MODEL_INPUT_DIM 4 +#define MAX_MODEL_OUTPUTS 12 + +typedef struct { + int num_input_dim; + iree_hal_dim_t input_shape[MAX_MODEL_INPUT_DIM]; + int input_length; + int input_size_bytes; + int num_output; + int output_length[MAX_MODEL_OUTPUTS]; + int output_size_bytes; + enum iree_hal_element_types_t hal_element_type; + char model_name[]; +} MlModel; + +#endif // SW_VEC_IREE_SAMPLES_UTIL_H_