/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ /** * @file * * This is a simple executor_runner that boots up the DSP, configures the serial * port, sends a bunch of test messages to the M33 core and then loads the model * defined in model_pte.h. It runs this model using the ops available in * cadence/ops directory. */ #include #include "fsl_device_registers.h" #include "fsl_mu.h" #include "board_hifi4.h" #include "model_pte.h" #include "pin_mux.h" #include // patternlint-disable executorch-cpp-nostdinc #include #include #include #include #include #include #include #include static uint8_t method_allocator_pool[18 * 1024U]; // 4 MB #include #define APP_MU MUB /* Flag indicates Core Boot Up*/ #define BOOT_FLAG 0x01U /* Channel transmit and receive register */ #define CHN_MU_REG_NUM 0U /* How many message is used to test message sending */ #define MSG_LENGTH 32U using executorch::runtime::Error; using executorch::runtime::Result; void LED_INIT(); void LED_TOGGLE(); void LED_INIT() { CLOCK_EnableClock(kCLOCK_HsGpio0); RESET_PeripheralReset(kHSGPIO0_RST_SHIFT_RSTn); gpio_pin_config_t pin_config = {kGPIO_DigitalOutput, LOGIC_LED_OFF}; GPIO_PinInit( BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, BOARD_LED_RED_GPIO_PIN, &pin_config); } void LED_TOGGLE() { LED_RED_TOGGLE(); } /*! * @brief Function to create delay for Led blink. */ void delay(void) { volatile uint32_t i = 0; for (i = 0; i < 50000000; ++i) { __NOP(); } } void et_pal_emit_log_message( et_timestamp_t timestamp, et_pal_log_level_t level, const char* filename, ET_UNUSED const char* function, size_t line, const char* message, ET_UNUSED size_t length) { PRINTF("\r%s\n", message); } int main(int argc, char** argv) { /* Init board hardware. */ BOARD_InitBootPins(); /* Initialize LED */ LED_INIT(); /* MUB init */ MU_Init(APP_MU); /* Send flag to Core 0 to indicate Core 1 has startup */ MU_SetFlags(APP_MU, BOOT_FLAG); BOARD_InitDebugConsole(); ET_LOG(Info, "Booted up in DSP."); executorch::runtime::runtime_init(); auto loader = executorch::extension::BufferDataLoader(model_pte, sizeof(model_pte)); Result program = executorch::runtime::Program::load(&loader); if (!program.ok()) { ET_LOG( Error, "ET: Program loading failed @ 0x%p: 0x%" PRIx32, model_pte, program.error()); } ET_LOG( Info, "AET: Model buffer loaded, has %u methods", program->num_methods()); const char* method_name = nullptr; { const auto method_name_result = program->get_method_name(0); ET_CHECK_MSG(method_name_result.ok(), "Program has no methods"); method_name = *method_name_result; } ET_LOG(Info, "ET: Running method %s", method_name); Result method_meta = program->method_meta(method_name); if (!method_meta.ok()) { ET_LOG( Error, "ET: Failed to get method_meta for %s: 0x%x", method_name, (unsigned int)method_meta.error()); } executorch::runtime::MemoryAllocator method_allocator{ executorch::runtime::MemoryAllocator( sizeof(method_allocator_pool), method_allocator_pool)}; std::vector> planned_buffers; // Owns the memory std::vector> planned_spans; // Passed to the allocator size_t num_memory_planned_buffers = method_meta->num_memory_planned_buffers(); for (size_t id = 0; id < num_memory_planned_buffers; ++id) { size_t buffer_size = static_cast(method_meta->memory_planned_buffer_size(id).get()); ET_LOG( Info, "ET: Setting up planned buffer %zu, size %zu.", id, buffer_size); planned_buffers.push_back(std::make_unique(buffer_size)); planned_spans.push_back({planned_buffers.back().get(), buffer_size}); } executorch::runtime::HierarchicalAllocator planned_memory( {planned_spans.data(), planned_spans.size()}); executorch::runtime::MemoryManager memory_manager( &method_allocator, &planned_memory); Result method = program->load_method(method_name, &memory_manager); if (!method.ok()) { ET_LOG( Error, "Loading of method %s failed with status 0x%" PRIx32, method_name, method.error()); } ET_LOG(Info, "Method loaded."); executorch::extension::prepare_input_tensors(*method); ET_LOG(Info, "Starting the model execution..."); Error status = method->execute(); ET_LOG(Info, "Executed model"); if (status != Error::Ok) { ET_LOG( Error, "Execution of method %s failed with status 0x%" PRIx32, method_name, status); } else { ET_LOG(Info, "Model executed successfully."); } std::vector outputs(method->outputs_size()); status = method->get_outputs(outputs.data(), outputs.size()); for (int i = 0; i < outputs.size(); ++i) { float* out_data_ptr = (float*)outputs[i].toTensor().const_data_ptr(); ET_LOG(Info, "First 20 elements of output %d", i); for (size_t j = 0; j < 20; j++) { ET_LOG(Info, "%f \n", out_data_ptr[j]); } } delay(); LED_TOGGLE(); return 0; }