xref: /aosp_15_r20/external/executorch/test/run_oss_cpp_tests.sh (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1#!/bin/bash
2# Copyright (c) Meta Platforms, Inc. and affiliates.
3# All rights reserved.
4#
5# This source code is licensed under the BSD-style license found in the
6# LICENSE file in the root directory of this source tree.
7
8# This script helps build and run C++ tests with CMakeLists.txt.
9# It builds and installs the root ExecuTorch package, and then sub-directories.
10#
11# If no arg is given, it probes all sub-directories containing
12# test/CMakeLists.txt. It builds and runs these tests.
13# If an arg is given, like `runtime/core/test/`, it runs that directory only.
14
15set -ex
16
17if [[ $(uname) == "Darwin" ]]; then
18  export LLVM_PROFDATA="${LLVM_PROFDATA:-xcrun llvm-profdata}"
19  export LLVM_COV="${LLVM_COV:-xcrun llvm-cov}"
20elif [[ $(uname) == "Linux" ]]; then
21  export LLVM_PROFDATA="${LLVM_PROFDATA:-llvm-profdata}"
22  export LLVM_COV="${LLVM_COV:-llvm-cov}"
23fi
24
25build_executorch() {
26  BUILD_VULKAN="OFF"
27  if [ -x "$(command -v glslc)" ]; then
28    BUILD_VULKAN="ON"
29  fi
30  cmake . \
31    -DCMAKE_INSTALL_PREFIX=cmake-out \
32    -DEXECUTORCH_USE_CPP_CODE_COVERAGE=ON \
33    -DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON \
34    -DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON \
35    -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
36    -DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
37    -DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \
38    -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
39    -DEXECUTORCH_BUILD_DEVTOOLS=ON \
40    -DEXECUTORCH_BUILD_VULKAN=$BUILD_VULKAN \
41    -DEXECUTORCH_BUILD_XNNPACK=ON \
42    -Bcmake-out
43  cmake --build cmake-out -j9 --target install
44}
45
46build_gtest() {
47  mkdir -p third-party/googletest/build
48  pushd third-party/googletest/build
49  cmake .. -DCMAKE_INSTALL_PREFIX=.
50  make -j4
51  make install
52  popd
53}
54
55export_test_model() {
56  python3 -m test.models.export_program --modules "ModuleAdd,ModuleAddHalf,ModuleDynamicCatUnallocatedIO,ModuleIndex,ModuleLinear,ModuleMultipleEntry,ModuleSimpleTrain" --outdir "cmake-out" 2> /dev/null
57  python3 -m test.models.export_delegated_program --modules "ModuleAddMul" --backend_id "StubBackend" --outdir "cmake-out" || true
58
59  DEPRECATED_ET_MODULE_LINEAR_CONSTANT_BUFFER_PATH="$(realpath test/models/deprecated/ModuleLinear-no-constant-segment.pte)"
60  ET_MODULE_ADD_HALF_PATH="$(realpath cmake-out/ModuleAddHalf.pte)"
61  ET_MODULE_ADD_PATH="$(realpath cmake-out/ModuleAdd.pte)"
62  ET_MODULE_DYNAMIC_CAT_UNALLOCATED_IO_PATH="$(realpath cmake-out/ModuleDynamicCatUnallocatedIO.pte)"
63  ET_MODULE_INDEX_PATH="$(realpath cmake-out/ModuleIndex.pte)"
64  ET_MODULE_LINEAR_PATH="$(realpath cmake-out/ModuleLinear.pte)"
65  ET_MODULE_MULTI_ENTRY_PATH="$(realpath cmake-out/ModuleMultipleEntry.pte)"
66  ET_MODULE_ADD_MUL_NOSEGMENTS_DA1024_PATH="$(realpath cmake-out/ModuleAddMul-nosegments-da1024.pte)"
67  ET_MODULE_ADD_MUL_NOSEGMENTS_PATH="$(realpath cmake-out/ModuleAddMul-nosegments.pte)"
68  ET_MODULE_ADD_MUL_PATH="$(realpath cmake-out/ModuleAddMul.pte)"
69  ET_MODULE_SIMPLE_TRAIN_PATH="$(realpath cmake-out/ModuleSimpleTrain.pte)"
70  export DEPRECATED_ET_MODULE_LINEAR_CONSTANT_BUFFER_PATH
71  export ET_MODULE_ADD_HALF_PATH
72  export ET_MODULE_ADD_PATH
73  export ET_MODULE_DYNAMIC_CAT_UNALLOCATED_IO_PATH
74  export ET_MODULE_INDEX_PATH
75  export ET_MODULE_LINEAR_PATH
76  export ET_MODULE_MULTI_ENTRY_PATH
77  export ET_MODULE_ADD_MUL_NOSEGMENTS_DA1024_PATH
78  export ET_MODULE_ADD_MUL_NOSEGMENTS_PATH
79  export ET_MODULE_ADD_MUL_PATH
80  export ET_MODULE_SIMPLE_TRAIN_PATH
81}
82
83build_and_run_test() {
84  local test_dir=$1
85  cmake "${test_dir}" \
86    -DCMAKE_BUILD_TYPE=Debug \
87    -DCMAKE_INSTALL_PREFIX=cmake-out \
88    -DEXECUTORCH_USE_CPP_CODE_COVERAGE=ON \
89    -DCMAKE_PREFIX_PATH="$(pwd)/third-party/googletest/build" \
90    -Bcmake-out/"${test_dir}"
91  cmake --build cmake-out/"${test_dir}" -j9
92
93  if [[ "$test_dir" =~ .*examples/models/llama/tokenizer.* ]]; then
94    RESOURCES_PATH=$(realpath examples/models/llama/tokenizer/test/resources)
95  elif [[ "$test_dir" =~ .*extension/llm/tokenizer.* ]]; then
96    RESOURCES_PATH=$(realpath extension/llm/tokenizer/test/resources)
97  else
98    RESOURCES_PATH=$(realpath extension/module/test/resources)
99  fi
100  export RESOURCES_PATH
101
102  for t in cmake-out/"${test_dir}"/*test; do
103    if [ -e "$t" ]; then
104      LLVM_PROFILE_FILE="cmake-out/$(basename $t).profraw" ./"$t";
105      TEST_BINARY_LIST="${TEST_BINARY_LIST} -object $t"
106    fi
107  done
108}
109
110report_coverage() {
111  ${LLVM_PROFDATA} merge -sparse cmake-out/*.profraw -o cmake-out/merged.profdata
112  ${LLVM_COV} report -instr-profile=cmake-out/merged.profdata $TEST_BINARY_LIST
113}
114
115probe_tests() {
116  # This function finds the set of directories that contain C++ tests
117  # CMakeLists.txt rules, that are buildable using build_and_run_test
118  dirs=(
119    backends
120    examples
121    extension
122    kernels
123    runtime
124    schema
125    devtools
126    test
127  )
128
129  find "${dirs[@]}" \
130      \( -type f -wholename '*/test/CMakeLists.txt' -exec dirname {} \; \) -o \
131      \( -type d -path '*/third-party/*' -prune \) \
132      | sort -u
133}
134
135build_executorch
136build_gtest
137export_test_model
138
139if [ -z "$1" ]; then
140  echo "Running all directories:"
141  probe_tests
142
143  for test_dir in $(probe_tests); do
144    build_and_run_test "${test_dir}"
145  done
146else
147  build_and_run_test "$1"
148fi
149
150report_coverage || true
151