diff --git a/backends/cadence/cadence.cmake b/backends/cadence/cadence.cmake index 1bd5a8db0e0..0eb3c2b5c76 100644 --- a/backends/cadence/cadence.cmake +++ b/backends/cadence/cadence.cmake @@ -15,6 +15,9 @@ endif() set(TOOLCHAIN_HOME ${XTENSA_TOOLCHAIN_PATH}/$ENV{TOOLCHAIN_VER}/XtensaTools) +set(CMAKE_SYSTEM_NAME Generic-ELF) +set(CMAKE_SYSTEM_PROCESSOR xtensa) + set(LINKER ld) set(BINTOOLS gnu) diff --git a/backends/cadence/executor_runner.cpp b/backends/cadence/executor_runner.cpp index 4e85a3b4564..a0cafcb96a5 100644 --- a/backends/cadence/executor_runner.cpp +++ b/backends/cadence/executor_runner.cpp @@ -49,6 +49,7 @@ static uint8_t method_allocator_pool[18 * 1024U]; // 4 MB using executorch::runtime::Error; using executorch::runtime::Result; +using executorch::runtime::EValue; void LED_INIT(); void LED_TOGGLE(); diff --git a/backends/cadence/hifi/operators/CMakeLists.txt b/backends/cadence/hifi/operators/CMakeLists.txt index 2e764541319..b698a252b24 100644 --- a/backends/cadence/hifi/operators/CMakeLists.txt +++ b/backends/cadence/hifi/operators/CMakeLists.txt @@ -170,7 +170,7 @@ generate_bindings_for_kernels( LIB_NAME "cadence_ops_lib" OPS_SCHEMA_YAML FUNCTIONS_YAML ${CMAKE_CURRENT_SOURCE_DIR}/../../aot/functions_hifi.yaml ) -message("Generated files ${gen_command_sources}") +message("Generated files: ${gen_command_sources}") gen_operators_lib( LIB_NAME "cadence_ops_lib" KERNEL_LIBS custom_ops DEPS aten_ops_cadence diff --git a/docs/source/backends-cadence.md b/docs/source/backends-cadence.md index c5a5fc8497a..6bea5541d6a 100644 --- a/docs/source/backends-cadence.md +++ b/docs/source/backends-cadence.md @@ -47,7 +47,9 @@ In order to be able to succesfully build and run ExecuTorch on a Xtensa HiFi4 DS - Needed to flash the board with the firmware images. You can install this on the same platform that you installed the MCUXpresso IDE on. - Note: depending on the version of the NXP board, another probe than JLink might be installed. In any case, flashing is done using the MCUXpresso IDE in a similar way. - [MCUXpresso SDK](https://mcuxpresso.nxp.com/en/select?device=EVK-MIMXRT685) - - Download this SDK to your Linux machine, extract it and take a note of the path where you store it. You'll need this later. + - Download this SDK, version 25.12.00 to your Linux machine, extract it and take a note of the path where you store it. You'll need this later. + - Note there are 2 variants of the SDK - the CLI only ARMGCC and for the MCUXpresso IDE. The SDK variant for the MCUXpresso IDE contains the SDK only for the i.MX RT600 platforms, whereas the ARMGCC toolchain contains the SDK for multiple SoCs. That means you need to adjust the env variables accordingly. + - If not noted otherwise, the links in this tutorial are valid for MCUXpresso SDK 25.12.00, MCUXPresso IDE variant. - [Xtensa compiler](https://tensilicatools.com/platform/i-mx-rt600/) - Download this to your Linux machine. This is needed to build ExecuTorch for the HiFi4 DSP. - For cases with optimized kernels, the [nnlib repo](https://github.com/foss-xtensa/nnlib-hifi4). @@ -264,7 +266,8 @@ export XTENSA_TOOLCHAIN=/home/user_name/cadence/XtDevTools/install/tools export TOOLCHAIN_VER=RI-2023.11-linux # The Xtensa core that you're targeting. # For HiFi4 (NXP RT600): -export XTENSA_CORE=VANILLA_HIFI +#export XTENSA_CORE=VANILLA_HIFI +export XTENSA_CORE=nxp_rt600_RI23_11_newlib # For Fusion G3: # export XTENSA_CORE=VANILLA_G3 # For Vision P6: @@ -278,11 +281,11 @@ The Cadence backend supports multiple DSP families: - **Vision P-Series DSPs**: Core `VANILLA_VISION`, enable with `-DEXECUTORCH_VISION_OPT=ON` ``` -***Step 2***. Clone the [nnlib repo](https://github.com/foss-xtensa/nnlib-hifi4), which contains optimized kernels and primitives for HiFi4 DSPs, with `git clone git@github.com:foss-xtensa/nnlib-hifi4.git`. +***Step 2***. Run the `backends/cadence/install_requirements.sh`. This clones the Cadence Neural Network Library (nn-lib) . ***Step 3***. Run the CMake build. In order to run the CMake build, you need the path to the following: -- The Program generated in the previous step +- The Program generated in the previous step, typically will have the name `CadenceDemoModel.pte`. - Path to the NXP SDK root. This should have been installed already in the [Setting up Developer Environment](#setting-up-developer-environment) section. This is the directory that contains the folders such as boards, components, devices, and other. ```bash @@ -307,7 +310,7 @@ cmake -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_PREFIX_PATH=/cmake-out \ -DMODEL_PATH= \ -DNXP_SDK_ROOT_DIR= \ - -DNN_LIB_BASE_DIR= \ + -DNN_LIB_BASE_DIR=/backends/cadence/hifi/third-party/nnlib/nnlib-hifi4 \ -Bcmake-out/examples/cadence \ examples/cadence @@ -316,8 +319,8 @@ cmake --build cmake-out/examples/cadence -j8 -t cadence_executorch_example After having succesfully run the above step you should see two binary files in their CMake output directory. ```bash -> ls cmake-xt/*.bin -cmake-xt/dsp_data_release.bin cmake-xt/dsp_text_release.bin +> ls cmake-out/examples/cadence/*.bin +cmake-out/examples/cadence/dsp_data_release.bin cmake-out/examples/cadence/dsp_text_release.bin ``` ## Deploying and Running on Device diff --git a/examples/cadence/CMakeLists.txt b/examples/cadence/CMakeLists.txt index 757009bd4df..b0f8fd7cc9e 100644 --- a/examples/cadence/CMakeLists.txt +++ b/examples/cadence/CMakeLists.txt @@ -26,7 +26,11 @@ if(NOT PYTHON_EXECUTABLE) endif() # Let files say "include ". -set(_common_include_directories ${EXECUTORCH_ROOT}/..) +set(_common_include_directories + ${EXECUTORCH_ROOT}/.. ${EXECUTORCH_ROOT}/runtime/core/portable_type/c10 +) + +add_compile_definitions(C10_USING_CUSTOM_GENERATED_MACROS) # Find prebuilt executorch lib find_package(executorch CONFIG REQUIRED) @@ -66,8 +70,8 @@ set(SOURCES ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/system_MIMXRT685S_dsp.c ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/utilities/debug_console_lite/fsl_assert.c ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/utilities/debug_console_lite/fsl_debug_console.c - ${NXP_SDK_ROOT_DIR}/boards/evkmimxrt685/dsp_examples/mu_polling/dsp/board_hifi4.c - ${NXP_SDK_ROOT_DIR}/boards/evkmimxrt685/dsp_examples/mu_polling/dsp/pin_mux.c + ${NXP_SDK_ROOT_DIR}/boards/evkmimxrt685/dsp_examples/mu_polling/hifi4/board_hifi4.c + ${NXP_SDK_ROOT_DIR}/boards/evkmimxrt685/dsp_examples/mu_polling/hifi4/pin_mux.c ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/utilities/str/fsl_str.c ) @@ -78,37 +82,63 @@ target_include_directories( PUBLIC ${NXP_SDK_ROOT_DIR} ${NXP_SDK_ROOT_DIR}/components/uart ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/drivers + ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/periph ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/utilities/debug_console_lite ${NXP_SDK_ROOT_DIR}/components/lists ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S ${NXP_SDK_ROOT_DIR}/CMSIS/Core/Include ${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/utilities/str - ${NXP_SDK_ROOT_DIR}/boards/evkmimxrt685/dsp_examples/mu_polling/dsp + ${NXP_SDK_ROOT_DIR}/boards/evkmimxrt685/dsp_examples/mu_polling/hifi4 ) -add_library(extension_runner_util STATIC IMPORTED) -set_property( - TARGET extension_runner_util - PROPERTY - IMPORTED_LOCATION - "${CMAKE_CURRENT_LIST_DIR}/../../cmake-out/extension/runner_util/libextension_runner_util.a" +add_subdirectory( + ${EXECUTORCH_ROOT}/backends/cadence/hifi/third-party/nnlib + ${CMAKE_CURRENT_BINARY_DIR}/backends/cadence/hifi/third-party/nnlib ) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/hifi/operators) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/hifi/kernels) +add_subdirectory( + ${EXECUTORCH_ROOT}/backends/cadence/hifi/operators + ${CMAKE_CURRENT_BINARY_DIR}/backends/cadence/hifi/operators +) +add_subdirectory( + ${EXECUTORCH_ROOT}/backends/cadence/hifi/kernels + ${CMAKE_CURRENT_BINARY_DIR}/backends/cadence/hifi/kernels +) + +# Generate C++ bindings to register kernels into both PyTorch (for AOT) and +# Executorch (for runtime). In order to fit the model into i.MXRT600 memory, we +# use selective kernel registration based on MODEL_PATH, and lik to +# cadence_ops_lib_selective. +gen_selected_ops( + LIB_NAME "cadence_ops_lib_selective" OPS_FROM_MODEL "${MODEL_PATH}" +) +generate_bindings_for_kernels( + LIB_NAME "cadence_ops_lib_selective" OPS_SCHEMA_YAML FUNCTIONS_YAML + ${EXECUTORCH_ROOT}/backends/cadence/aot/functions_hifi.yaml +) +message("Generated files: ${gen_command_sources}") + +gen_operators_lib( + LIB_NAME "cadence_ops_lib_selective" KERNEL_LIBS custom_ops DEPS + aten_ops_cadence +) # Generate the model header file add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/model_pte.h - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/utils/gen_header.py - --model_path ${MODEL_PATH} --header_output_path ${CMAKE_BINARY_DIR} + COMMAND + ${PYTHON_EXECUTABLE} ${EXECUTORCH_ROOT}/backends/cadence/utils/gen_header.py + --model_path ${MODEL_PATH} --header_output_path ${CMAKE_BINARY_DIR} COMMENT "Converting .pte model to header file..." - DEPENDS ${CMAKE_CURRENT_LIST_DIR}/utils/gen_header.py + DEPENDS ${EXECUTORCH_ROOT}/backends/cadence/utils/gen_header.py ) add_custom_target(gen_model_header DEPENDS ${CMAKE_BINARY_DIR}/model_pte.h) -add_executable(cadence_executorch_example executor_runner.cpp) +add_executable( + cadence_executorch_example + ${EXECUTORCH_ROOT}/backends/cadence/executor_runner.cpp +) add_dependencies(cadence_executorch_example gen_model_header) # lint_cmake: -linelength @@ -120,9 +150,10 @@ target_include_directories( target_link_options( cadence_executorch_example PRIVATE -mlsp=${NXP_SDK_ROOT_DIR}/devices/MIMXRT685S/xtensa/min-rt + -Wl,--orphan-handling=place ) target_link_libraries( - cadence_executorch_example dsp_mu_polling_libs cadence_ops_lib + cadence_executorch_example dsp_mu_polling_libs cadence_ops_lib_selective extension_runner_util executorch ) @@ -130,12 +161,13 @@ add_custom_command( TARGET cadence_executorch_example POST_BUILD COMMAND - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/utils/post_compilation.py - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME} ${CMAKE_BINARY_DIR} + ${PYTHON_EXECUTABLE} + ${EXECUTORCH_ROOT}/backends/cadence/utils/post_compilation.py + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR} COMMENT "Generating .bin files that can be used to flash the DSP with. Copy over the dsp_text_release.bin and dsp_data_release.bin that are generated into your NXP MCUXpresso IDE workspace and flash the DSP with these binaries." DEPENDS - ${CMAKE_CURRENT_LIST_DIR}/utils/post_compilation.py + ${EXECUTORCH_ROOT}/backends/cadence/utils/post_compilation.py ) diff --git a/tools/cmake/Codegen.cmake b/tools/cmake/Codegen.cmake index e838e62c582..b39c9a7f472 100644 --- a/tools/cmake/Codegen.cmake +++ b/tools/cmake/Codegen.cmake @@ -158,6 +158,7 @@ function(generate_bindings_for_kernels) ) endif() + message("Command - ${_gen_command}") add_custom_command( COMMENT "Generating code for kernel registration" OUTPUT ${_gen_command_sources}