Jelajahi Sumber

CMSIS-NN: Run unit test with FVP

* Add option to use FVP based Arm Corstone-300 software for unit testing.
* Update README with this information.

Change-Id: Ib2003c277865786a799c91fb6cd5b924ebdab26f
Måns Nilsson 5 tahun lalu
induk
melakukan
d803502b95

+ 38 - 5
CMSIS/NN/Tests/UnitTest/CMakeLists.txt

@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+# Copyright (c) 2019-2021 Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -27,6 +27,9 @@ set(CMAKE_EXECUTABLE_SUFFIX ".elf")
 set(UART0_BASE "0x49303000" CACHE STRING "UART base address.")
 set(UART_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../drivers/uart" CACHE PATH "Path to UART.")
 set(LINK_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../platform/fastmodels/model" CACHE PATH "Linker file.")
+set(USE_ETHOSU_CORE_PLATFORM_DEFAULT OFF)
+set(ETHOSU_CORE_PLATFORM_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../core_platform" CACHE PATH "Path to Arm Ethos-U Core Platform project.")
+set(FVP_CORSTONE_300_PATH "${ETHOSU_CORE_PLATFORM_PATH}/targets/corstone-300")
 
 set_property(GLOBAL PROPERTY cmsis_nn_unit_test_executables)
 
@@ -75,6 +78,17 @@ MESSAGE(STATUS "Downloading Unity and generating test runners for CMSIS-NN unit
 execute_process(COMMAND ${MAKE_CMD} ${MAKE_CMD_SCRIPT} ${MAKE_CMD_SCRIPT_OPTION}
                         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 add_subdirectory(Unity)
+
+option(USE_ETHOSU_CORE_PLATFORM "Use Arm Ethos-U Core Platform project." ${USE_ETHOSU_CORE_PLATFORM_DEFAULT})
+
+if(USE_ETHOSU_CORE_PLATFORM)
+add_subdirectory(${FVP_CORSTONE_300_PATH} fvp_corstone_300)
+
+add_library(retarget STATIC
+                     ${FVP_CORSTONE_300_PATH}/retarget.c
+                     ${FVP_CORSTONE_300_PATH}/uart.c)
+
+else()
 add_subdirectory(${UART_PATH} uart)
 
 include(Platform/cmsis_device.cmake)
@@ -97,13 +111,32 @@ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
 endif()
 set(LINK_FILE_OUT ${LINK_FILE}.${LINK_FILE_EXT})
 
-# Link in dependecies to every unit test.
+endif()
+
+# Link in dependencies to every unit test.
 get_property(executables GLOBAL PROPERTY cmsis_nn_unit_test_executables)
 string(REPLACE " " ";" cmsis_nn_unit_test_list_of_executables ${executables})
 foreach(target ${cmsis_nn_unit_test_list_of_executables})
     target_link_libraries(${target} PRIVATE $<TARGET_OBJECTS:retarget> retarget)
-    target_link_libraries(${target} PRIVATE $<TARGET_OBJECTS:cmsis_startup> cmsis_startup)
+    target_link_libraries(${target} PRIVATE $<TARGET_OBJECTS:cmsis_startup> cmsis_device)
     add_dependencies(${target} retarget cmsis_startup)
-    target_link_options(${target} PRIVATE ${LINK_FILE_OPTION} ${LINK_FILE_OUT} ${LINK_ENTRY_OPTION} ${LINK_ENTRY})
-    set_target_properties(${target} PROPERTIES LINK_DEPENDS ${LINK_FILE_OUT})
+    if(USE_ETHOSU_CORE_PLATFORM)
+
+        target_compile_definitions(${target} PUBLIC USING_FVP_CORSTONE_300)
+        target_link_options(${target} PRIVATE --entry Reset_Handler)
+
+        # Copy linker files.
+        if (CMAKE_CXX_COMPILER_ID STREQUAL "ARMClang")
+            configure_file(${FVP_CORSTONE_300_PATH}/platform.scatter
+            ${CMAKE_CURRENT_SOURCE_DIR}/platform_${target}.scatter COPYONLY)
+        elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+            configure_file(${FVP_CORSTONE_300_PATH}/platform.ld
+            ${CMAKE_CURRENT_SOURCE_DIR}/platform_${target}.ld COPYONLY)
+        endif()
+
+        ethosu_link_options(${target} PRIVATE LINK_FILE platform_${target})
+     else()
+        target_link_options(${target} PRIVATE ${LINK_FILE_OPTION} ${LINK_FILE_OUT} ${LINK_ENTRY_OPTION} ${LINK_ENTRY})
+        set_target_properties(${target} PROPERTIES LINK_DEPENDS ${LINK_FILE_OUT})
+    endif()
 endforeach()

+ 33 - 2
CMSIS/NN/Tests/UnitTest/README.md

@@ -56,14 +56,45 @@ UART and LINK_FILE have default values but you most probably need to replace the
     ```make```
 ```
 
-Some examples using Uart and toolchain in Ethos-u-core_software project. See : https://review.mlplatform.org/admin/repos/ml/ethos-u/ethos-u-core-software
-
+Some examples using Uart and toolchain in Arm Ethos-U Core Software project. See : https://review.mlplatform.org/admin/repos/ml/ethos-u/ethos-u-core-software
 
 ```
     ```cmake .. -DCMAKE_TOOLCHAIN_FILE=~/ethos-u-core-software/cmake/toolchain/arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m7 -DUART_PATH=~/ethos-u-core-software/drivers/uart -DLINK_FILE=~/platform/fastmodels/model```
     ```cmake .. -DCMAKE_TOOLCHAIN_FILE=~/ethos-u-core-software/cmake/toolchain/arm-none-eabi-gcc.cmake -DCMAKE_SYSTEM_PROCESSOR=cortex-m55 -DUART_PATH=~/ethos-u-core-software/drivers/uart -DLINK_FILE=~/platform/fastmodels/model```
 ```
 
+If using Cmake it is recommended to use Arm Ethos-U Core Platform project (https://review.mlplatform.org/admin/repos/ml/ethos-u/ethos-u-core-platform) and a fixed virtual platform (FVP) based on Arm Corstone-300 software (https://developer.arm.com/ip-products/subsystem/corstone/corstone-300). First clone Arm Ethos-U Core Software and Arm Ethos-U Core Platform into same directory. Then build:
+
+```
+    ```mkdir build```
+    ```cd build```
+    ```cmake .. -DCMAKE_TOOLCHAIN_FILE=</path/to/Ethos-u-core-platform>/cmake/toolchain/.cmake -DETHOSU_CORE_PLATFORM_PATH=</path/to/Ethos-u-core-platform> -DUSE_ETHOSU_CORE_PLATFORM=ON -DTARGET_CPU=cortex-m55```
+    ```make test_arm_depthwise_conv_s8_opt```
+```
+Note that here you may want to specifiy the unit test targets to build otherwise it will build external targets as well. Some more examples, assuming Ethos-u-core-platform and Ethos-u-core_software are cloned into your home directory:
+
+```
+    ```cmake .. -DCMAKE_TOOLCHAIN_FILE=~/core_platform/cmake/toolchain/arm-none-eabi-gcc.cmake -DETHOSU_CORE_PLATFORM_PATH=~/core_platform -DUSE_ETHOSU_CORE_PLATFORM=ON -DTARGET_CPU=cortex-m55```
+    ```cmake .. -DCMAKE_TOOLCHAIN_FILE=~/core_platform/cmake/toolchain/arm-none-eabi-gcc.cmake -DETHOSU_CORE_PLATFORM_PATH=~/core_platform -DUSE_ETHOSU_CORE_PLATFORM=ON -DTARGET_CPU=cortex-m7```
+    ```cmake .. -DCMAKE_TOOLCHAIN_FILE=~/core_platform/cmake/toolchain/armclang.cmake -DETHOSU_CORE_PLATFORM_PATH=~/core_platform -DUSE_ETHOSU_CORE_PLATFORM=ON -DTARGET_CPU=cortex-m3```
+```
+
+Then you need to download and install the FVP based Arm Corstone-300 software, for example:
+
+```
+mkdir -p /home/$user/FVP
+wget https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-300/FVP_Corstone_SSE-300_Ethos-U55_11.12_57.tgz
+tar -xvzf FVP_Corstone_SSE-300_Ethos-U55_11.12_57.tgz
+./FVP_Corstone_SSE-300_Ethos-U55.sh --i-agree-to-the-contained-eula --no-interactive -d /home/$user/FVP
+export PATH="/home/$user/FVP/models/Linux64_GCC-6.4:$PATH"
+```
+
+Finally you can run the unit tests. For example:
+
+```
+FVP_Corstone_SSE-300_Ethos-U55 --cpulimit 2 -C mps3_board.visualisation.disable-visualisation=1 -C mps3_board.telnetterminal0.start_telnet=0 -C mps3_board.uart0.out_file="-" -C mps3_board.uart0.unbuffered_output=1 ./TestCases/test_arm_depthwise_conv_s8_opt/test_arm_depthwise_conv_s8_opt.elf
+```
+
 ## Generating new test data
 Generating new test data is done with the following script. Use the -h flag to get more info.
 

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s8/Unity/unity_test_arm_avgpool_s8.c

@@ -25,11 +25,18 @@
 #include "../test_arm_avgpool_s8.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_convolve_1x1_s8_fast/Unity/unity_test_arm_convolve_1x1_s8_fast.c

@@ -25,11 +25,18 @@
 #include "../test_arm_convolve_1x1_s8_fast.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_convolve_s8/Unity/unity_test_arm_convolve_s8.c

@@ -25,11 +25,18 @@
 #include "../test_arm_convolve_s8.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_depthwise_conv_3x3_s8/Unity/unity_test_arm_depthwise_conv_3x3_s8.c

@@ -25,11 +25,18 @@
 #include "../test_arm_depthwise_conv_3x3_s8.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_depthwise_conv_s8/Unity/unity_test_arm_depthwise_conv_s8.c

@@ -25,11 +25,18 @@
 #include "../test_arm_depthwise_conv_s8.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_depthwise_conv_s8_opt/Unity/unity_test_arm_depthwise_conv_s8_opt.c

@@ -25,11 +25,18 @@
 #include "../test_arm_depthwise_conv_s8_opt.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_fully_connected_s8/Unity/unity_test_arm_fully_connected_s8.c

@@ -25,11 +25,18 @@
 #include "../test_arm_fully_connected_s8.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.

+ 7 - 0
CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s8/Unity/unity_test_arm_max_pool_s8.c

@@ -25,11 +25,18 @@
 #include "../test_arm_max_pool_s8.c"
 #include "unity.h"
 
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
 /* This function is called from the autogenerated file.
  * The name must be exactly like this
  */
 void setUp(void)
 { /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+    uart_init();
+#endif
 }
 
 /* This function is called from the autogenerated file.