1# 2# SPDX-FileCopyrightText: Copyright 2019-2024 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(-fomit-frame-pointer 26 -Werror 27 -Wimplicit-function-declaration 28 -Wunused-variable 29 -Wunused-function 30 -Wno-redundant-decls 31 -Wvla) 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) 54add_compile_options(${CMSIS_OPTIMIZATION_LEVEL}) 55 56# Target for all unit tests. 57add_custom_target(cmsis_nn_unit_tests) 58 59# This function should be used instead of add_executable. 60set_property(GLOBAL PROPERTY cmsis_nn_unit_test_executables) 61function(add_cmsis_nn_unit_test_executable) 62 get_property(tmp GLOBAL PROPERTY cmsis_nn_unit_test_executables) 63 foreach(target ${ARGV}) 64 set(tmp "${tmp} ${target}") 65 add_executable(${target}) 66 if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 67 target_link_options(${target} PRIVATE "--specs=nosys.specs") 68 endif() 69 add_dependencies(cmsis_nn_unit_tests ${target}) 70 endforeach() 71 set_property(GLOBAL PROPERTY cmsis_nn_unit_test_executables "${tmp}") 72endfunction(add_cmsis_nn_unit_test_executable) 73 74add_subdirectory(TestCases/test_arm_avgpool_s16) 75add_subdirectory(TestCases/test_arm_avgpool_s8) 76add_subdirectory(TestCases/test_arm_convolve_1x1_s8_fast) 77add_subdirectory(TestCases/test_arm_convolve_1x1_s4_fast) 78add_subdirectory(TestCases/test_arm_convolve_s16) 79add_subdirectory(TestCases/test_arm_convolve_s8) 80add_subdirectory(TestCases/test_arm_convolve_s4) 81add_subdirectory(TestCases/test_arm_convolve_1_x_n_s8) 82add_subdirectory(TestCases/test_arm_depthwise_conv_3x3_s8) 83add_subdirectory(TestCases/test_arm_depthwise_conv_fast_s16) 84add_subdirectory(TestCases/test_arm_depthwise_conv_s16) 85add_subdirectory(TestCases/test_arm_depthwise_conv_s4) 86add_subdirectory(TestCases/test_arm_depthwise_conv_s4_opt) 87add_subdirectory(TestCases/test_arm_depthwise_conv_s8) 88add_subdirectory(TestCases/test_arm_depthwise_conv_s8_opt) 89add_subdirectory(TestCases/test_arm_ds_cnn_l_s8) 90add_subdirectory(TestCases/test_arm_ds_cnn_s_s8) 91add_subdirectory(TestCases/test_arm_elementwise_add_s16) 92add_subdirectory(TestCases/test_arm_elementwise_add_s8) 93add_subdirectory(TestCases/test_arm_elementwise_mul_s16) 94add_subdirectory(TestCases/test_arm_elementwise_mul_s8) 95add_subdirectory(TestCases/test_arm_fully_connected_s16) 96add_subdirectory(TestCases/test_arm_fully_connected_s8) 97add_subdirectory(TestCases/test_arm_fully_connected_s4) 98add_subdirectory(TestCases/test_arm_grouped_convolve_s8) 99add_subdirectory(TestCases/test_arm_lstm_unidirectional_s8) 100add_subdirectory(TestCases/test_arm_max_pool_s16) 101add_subdirectory(TestCases/test_arm_max_pool_s8) 102add_subdirectory(TestCases/test_arm_softmax_s16) 103add_subdirectory(TestCases/test_arm_softmax_s8) 104add_subdirectory(TestCases/test_arm_softmax_s8_s16) 105add_subdirectory(TestCases/test_arm_svdf_s8) 106add_subdirectory(TestCases/test_arm_svdf_state_s16_s8) 107add_subdirectory(TestCases/test_arm_transpose_conv_s8) 108add_subdirectory(TestCases/test_arm_lstm_unidirectional_s16) 109 110set(MAKE_CMD "python3") 111set(MAKE_CMD_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/unittest_targets.py") 112set(MAKE_CMD_SCRIPT_OPTION "--download-and-generate-test-runners") 113MESSAGE(STATUS "Downloading Unity and generating test runners for CMSIS-NN unit tests if needed..") 114execute_process(COMMAND ${MAKE_CMD} ${MAKE_CMD_SCRIPT} ${MAKE_CMD_SCRIPT_OPTION} 115 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 116add_subdirectory(Unity) 117 118# Link common dependencies. 119get_property(executables GLOBAL PROPERTY cmsis_nn_unit_test_executables) 120string(REPLACE " " ";" cmsis_nn_unit_test_list_of_executables ${executables}) 121foreach(target ${cmsis_nn_unit_test_list_of_executables}) 122 target_link_libraries(${target} LINK_PUBLIC unity) 123 target_link_libraries(${target} LINK_PUBLIC cmsis-nn) 124endforeach() 125 126if(BUILD_CMSIS_NN_UNIT_TESTS_FOR_FVP_BASED_CORSTONE_300) 127 add_library(retarget STATIC 128 ${FVP_CORSTONE_300_PATH}/retarget.c 129 ${FVP_CORSTONE_300_PATH}/uart.c) 130 131 # Build CMSIS startup dependencies based on TARGET_CPU. 132 string(REGEX REPLACE "^cortex-m([0-9]+)$" "ARMCM\\1" ARM_CPU ${CMAKE_SYSTEM_PROCESSOR}) 133 if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m33") 134 set(ARM_FEATURES "_DSP_FP") 135 elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m4") 136 set(ARM_FEATURES "_FP") 137 elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "cortex-m7") 138 set(ARM_FEATURES "_DP") 139 else() 140 set(ARM_FEATURES "") 141 endif() 142 add_library(cmsis_startup STATIC) 143 target_sources(cmsis_startup PRIVATE 144 ${CMSIS_PATH}/Device/ARM/${ARM_CPU}/Source/startup_${ARM_CPU}.c 145 ${CMSIS_PATH}/Device/ARM/${ARM_CPU}/Source/system_${ARM_CPU}.c) 146 target_include_directories(cmsis_startup PUBLIC 147 ${CMSIS_PATH}/Device/ARM/${ARM_CPU}/Include 148 ${CMSIS_PATH}/CMSIS/Core/Include) 149 target_compile_options(cmsis_startup INTERFACE -include${ARM_CPU}${ARM_FEATURES}.h) 150 target_compile_definitions(cmsis_startup PRIVATE ${ARM_CPU}${ARM_FEATURES}) 151 152 # Linker file settings. 153 set(LINK_FILE "${FVP_CORSTONE_300_PATH}/linker" CACHE PATH "Linker file.") 154 if (CMAKE_CXX_COMPILER_ID STREQUAL "ARMClang") 155 set(LINK_FILE "${FVP_CORSTONE_300_PATH}/linker.scatter") 156 set(LINK_FILE_OPTION "--scatter") 157 set(LINK_ENTRY_OPTION "--entry") 158 set(LINK_ENTRY "Reset_Handler") 159 elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 160 set(LINK_FILE "${FVP_CORSTONE_300_PATH}/linker.ld") 161 set(LINK_FILE_OPTION "-T") 162 set(LINK_ENTRY_OPTION "") 163 set(LINK_ENTRY "") 164 endif() 165 166 # Link in FVP dependencies to every unit test. 167 get_property(executables GLOBAL PROPERTY cmsis_nn_unit_test_executables) 168 string(REPLACE " " ";" cmsis_nn_unit_test_list_of_executables ${executables}) 169 foreach(target ${cmsis_nn_unit_test_list_of_executables}) 170 target_link_libraries(${target} PRIVATE retarget) 171 target_link_libraries(${target} PRIVATE $<TARGET_OBJECTS:cmsis_startup> cmsis_startup) 172 173 add_dependencies(${target} retarget cmsis_startup) 174 175 target_compile_definitions(${target} PUBLIC USING_FVP_CORSTONE_300) 176 177 target_link_options(${target} PRIVATE ${LINK_FILE_OPTION} ${LINK_FILE} ${LINK_ENTRY_OPTION} ${LINK_ENTRY}) 178 set_target_properties(${target} PROPERTIES LINK_DEPENDS ${LINK_FILE}) 179 endforeach() 180endif() 181