1# 2# SPDX-FileCopyrightText: Copyright 2019-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> 3# 4# SPDX-License-Identifier: Apache-2.0 5# 6# Licensed under the Apache License, Version 2.0 (the License); you may 7# not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an AS IS BASIS, WITHOUT 14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19cmake_minimum_required(VERSION 3.15.6) 20 21project(cmsis_nn_unit_tests VERSION 0.0.1) 22 23set(CMSIS_PATH "</path/to/CMSIS>" CACHE PATH "Path to CMSIS.") 24 25add_compile_options(-Ofast 26 -fomit-frame-pointer 27 -Werror 28 -Wimplicit-function-declaration 29 -Wunused-variable 30 -Wunused-function 31 -Wno-redundant-decls) 32 33option(BUILD_CMSIS_NN_UNIT "If building the unit tests from another project, i.e. \ 34platform dependencies need to be provided externally." OFF) 35 36if (${CMSIS_PATH} STREQUAL "</path/to/CMSIS>") 37 message(FATAL_ERROR "CMSIS_PATH not set. Did you provide -DCMSIS_PATH=<path/to/CMSIS>?") 38endif() 39 40if(NOT BUILD_CMSIS_NN_UNIT) 41 set(BUILD_CMSIS_NN_UNIT_TESTS_FOR_FVP_BASED_CORSTONE_300 ON) 42else() 43 set(BUILD_CMSIS_NN_UNIT_TESTS_FOR_FVP_BASED_CORSTONE_300 OFF) 44endif() 45 46if(BUILD_CMSIS_NN_UNIT_TESTS_FOR_FVP_BASED_CORSTONE_300) 47 set(FVP_CORSTONE_300_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Corstone-300" CACHE PATH 48 "Dependencies for using FVP based on Arm Corstone-300 software.") 49 set(CMAKE_EXECUTABLE_SUFFIX ".elf") 50endif() 51 52# Build the functions to be tested. 53add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../.. cmsis-nn) 54 55# Target for all unit tests. 56add_custom_target(cmsis_nn_unit_tests) 57 58# This function should be used instead of add_executable. 59set_property(GLOBAL PROPERTY cmsis_nn_unit_test_executables) 60function(add_cmsis_nn_unit_test_executable) 61 get_property(tmp GLOBAL PROPERTY cmsis_nn_unit_test_executables) 62 foreach(target ${ARGV}) 63 set(tmp "${tmp} ${target}") 64 add_executable(${target}) 65 if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 66 target_link_options(${target} PRIVATE "--specs=nosys.specs") 67 endif() 68 add_dependencies(cmsis_nn_unit_tests ${target}) 69 endforeach() 70 set_property(GLOBAL PROPERTY cmsis_nn_unit_test_executables "${tmp}") 71endfunction(add_cmsis_nn_unit_test_executable) 72 73add_subdirectory(TestCases/test_arm_avgpool_s16) 74add_subdirectory(TestCases/test_arm_avgpool_s8) 75add_subdirectory(TestCases/test_arm_convolve_1x1_s8_fast) 76add_subdirectory(TestCases/test_arm_convolve_fast_s16) 77add_subdirectory(TestCases/test_arm_convolve_s16) 78add_subdirectory(TestCases/test_arm_convolve_s8) 79add_subdirectory(TestCases/test_arm_convolve_1_x_n_s8) 80add_subdirectory(TestCases/test_arm_depthwise_conv_3x3_s8) 81add_subdirectory(TestCases/test_arm_depthwise_conv_fast_s16) 82add_subdirectory(TestCases/test_arm_depthwise_conv_s16) 83add_subdirectory(TestCases/test_arm_depthwise_conv_s8) 84add_subdirectory(TestCases/test_arm_depthwise_conv_s8_opt) 85add_subdirectory(TestCases/test_arm_elementwise_add_s16) 86add_subdirectory(TestCases/test_arm_elementwise_add_s8) 87add_subdirectory(TestCases/test_arm_elementwise_mul_s16) 88add_subdirectory(TestCases/test_arm_elementwise_mul_s8) 89add_subdirectory(TestCases/test_arm_fully_connected_s16) 90add_subdirectory(TestCases/test_arm_fully_connected_s8) 91add_subdirectory(TestCases/test_arm_lstm_unidirectional_s16_s8) 92add_subdirectory(TestCases/test_arm_max_pool_s16) 93add_subdirectory(TestCases/test_arm_max_pool_s8) 94add_subdirectory(TestCases/test_arm_softmax_s16) 95add_subdirectory(TestCases/test_arm_softmax_s8) 96add_subdirectory(TestCases/test_arm_softmax_s8_s16) 97add_subdirectory(TestCases/test_arm_svdf_s8) 98add_subdirectory(TestCases/test_arm_svdf_state_s16_s8) 99add_subdirectory(TestCases/test_arm_ds_cnn_l_s8) 100add_subdirectory(TestCases/test_arm_ds_cnn_s_s8) 101 102set(MAKE_CMD "python3") 103set(MAKE_CMD_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/unittest_targets.py") 104set(MAKE_CMD_SCRIPT_OPTION "--download-and-generate-test-runners") 105set(MAKE_CMD_SCRIPT_CMSIS_PATH "-p ${CMSIS_PATH}") 106MESSAGE(STATUS "Downloading Unity and generating test runners for CMSIS-NN unit tests if needed..") 107execute_process(COMMAND ${MAKE_CMD} ${MAKE_CMD_SCRIPT} ${MAKE_CMD_SCRIPT_OPTION} ${MAKE_CMD_SCRIPT_CMSIS_PATH} 108 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 109add_subdirectory(Unity) 110 111# Link common dependencies. 112get_property(executables GLOBAL PROPERTY cmsis_nn_unit_test_executables) 113string(REPLACE " " ";" cmsis_nn_unit_test_list_of_executables ${executables}) 114foreach(target ${cmsis_nn_unit_test_list_of_executables}) 115 target_link_libraries(${target} LINK_PUBLIC unity) 116 target_link_libraries(${target} LINK_PUBLIC cmsis-nn) 117endforeach() 118 119if(BUILD_CMSIS_NN_UNIT_TESTS_FOR_FVP_BASED_CORSTONE_300) 120 add_library(retarget STATIC 121 ${FVP_CORSTONE_300_PATH}/retarget.c 122 ${FVP_CORSTONE_300_PATH}/uart.c) 123 124 # Build CMSIS startup dependencies based on TARGET_CPU. 125 string(REGEX REPLACE "^cortex-m([0-9]+)$" "ARMCM\\1" ARM_CPU ${CMAKE_SYSTEM_PROCESSOR}) 126 if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m33") 127 set(ARM_FEATURES "_DSP_FP") 128 elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m4") 129 set(ARM_FEATURES "_FP") 130 elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m7") 131 set(ARM_FEATURES "_DP") 132 else() 133 set(ARM_FEATURES "") 134 endif() 135 add_library(cmsis_startup STATIC) 136 target_sources(cmsis_startup PRIVATE 137 ${CMSIS_PATH}/Device/ARM/${ARM_CPU}/Source/startup_${ARM_CPU}.c 138 ${CMSIS_PATH}/Device/ARM/${ARM_CPU}/Source/system_${ARM_CPU}.c) 139 target_include_directories(cmsis_startup PUBLIC 140 ${CMSIS_PATH}/Device/ARM/${ARM_CPU}/Include 141 ${CMSIS_PATH}/CMSIS/Core/Include) 142 target_compile_options(cmsis_startup INTERFACE -include${ARM_CPU}${ARM_FEATURES}.h) 143 target_compile_definitions(cmsis_startup PRIVATE ${ARM_CPU}${ARM_FEATURES}) 144 145 # Linker file settings. 146 set(LINK_FILE "${FVP_CORSTONE_300_PATH}/linker" CACHE PATH "Linker file.") 147 if (CMAKE_CXX_COMPILER_ID STREQUAL "ARMClang") 148 set(LINK_FILE "${FVP_CORSTONE_300_PATH}/linker.scatter") 149 set(LINK_FILE_OPTION "--scatter") 150 set(LINK_ENTRY_OPTION "--entry") 151 set(LINK_ENTRY "Reset_Handler") 152 elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 153 set(LINK_FILE "${FVP_CORSTONE_300_PATH}/linker.ld") 154 set(LINK_FILE_OPTION "-T") 155 set(LINK_ENTRY_OPTION "") 156 set(LINK_ENTRY "") 157 endif() 158 159 # Link in FVP dependencies to every unit test. 160 get_property(executables GLOBAL PROPERTY cmsis_nn_unit_test_executables) 161 string(REPLACE " " ";" cmsis_nn_unit_test_list_of_executables ${executables}) 162 foreach(target ${cmsis_nn_unit_test_list_of_executables}) 163 target_link_libraries(${target} PRIVATE retarget) 164 target_link_libraries(${target} PRIVATE $<TARGET_OBJECTS:cmsis_startup> cmsis_startup) 165 166 add_dependencies(${target} retarget cmsis_startup) 167 168 target_compile_definitions(${target} PUBLIC USING_FVP_CORSTONE_300) 169 170 target_link_options(${target} PRIVATE ${LINK_FILE_OPTION} ${LINK_FILE} ${LINK_ENTRY_OPTION} ${LINK_ENTRY}) 171 set_target_properties(${target} PROPERTIES LINK_DEPENDS ${LINK_FILE}) 172 endforeach() 173endif() 174