Skip to content

Commit 802d148

Browse files
authored
Merge branch 'main' into op_support
2 parents f3e823e + 5cd973c commit 802d148

File tree

79 files changed

+1017
-650
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1017
-650
lines changed

.ci/docker/build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ case "${IMAGE_NAME}" in
4848
executorch-ubuntu-22.04-mediatek-sdk)
4949
MEDIATEK_SDK=yes
5050
CLANG_VERSION=12
51+
ANDROID_NDK_VERSION=r27b
5152
;;
5253
executorch-ubuntu-22.04-clang12-android)
5354
LINTRUNNER=""

.ci/scripts/build_llama_android.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,5 @@ build_llama_runner() {
6060

6161
cmake --build cmake-android-out/examples/models/llama -j4 --config Release
6262
}
63-
install_flatc_from_source
6463
install_executorch_and_backend_lib
6564
build_llama_runner
File renamed without changes.

.ci/scripts/test_model.sh

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,14 @@ test_model_with_qnn() {
209209
EXPORTED_MODEL=$(find "./${EXPORT_SCRIPT}" -type f -name "${MODEL_NAME}*.pte" -print -quit)
210210
}
211211

212+
# Run CoreML tests.
213+
#
214+
# @param should_test If true, build and test the model using the coreml_executor_runner.
212215
test_model_with_coreml() {
213-
if [[ "${BUILD_TOOL}" == "buck2" ]]; then
214-
echo "coreml doesn't support buck2."
216+
local should_test="$1"
217+
218+
if [[ "${BUILD_TOOL}" != "cmake" ]]; then
219+
echo "coreml only supports cmake."
215220
exit 1
216221
fi
217222

@@ -229,6 +234,14 @@ test_model_with_coreml() {
229234
echo "No .pte file found"
230235
exit 1
231236
fi
237+
238+
# Run the model
239+
if [ "${should_test}" = true ]; then
240+
echo "Testing exported model with coreml_executor_runner..."
241+
local out_dir=$(mktemp -d)
242+
COREML_EXECUTOR_RUNNER_OUT_DIR="${out_dir}" examples/apple/coreml/scripts/build_executor_runner.sh
243+
"${out_dir}/coreml_executor_runner" --model_path "${EXPORTED_MODEL}"
244+
fi
232245
}
233246

234247
test_model_with_mps() {
@@ -247,7 +260,11 @@ elif [[ "${BACKEND}" == *"qnn"* ]]; then
247260
fi
248261
elif [[ "${BACKEND}" == *"coreml"* ]]; then
249262
echo "Testing ${MODEL_NAME} with coreml..."
250-
test_model_with_coreml
263+
should_test_coreml=false
264+
if [[ "${BACKEND}" == *"test"* ]]; then
265+
should_test_coreml=true
266+
fi
267+
test_model_with_coreml "${should_test_coreml}"
251268
if [[ $? -eq 0 ]]; then
252269
prepare_artifacts_upload
253270
fi

.ci/scripts/utils.sh

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,6 @@ install_pytorch_and_domains() {
8080
sccache --show-stats || true
8181
}
8282

83-
install_flatc_from_source() {
84-
# NB: This function could be used to install flatbuffer from source
85-
pushd third-party/flatbuffers || return
86-
87-
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
88-
if [ "$(uname)" == "Darwin" ]; then
89-
CMAKE_JOBS=$(( $(sysctl -n hw.ncpu) - 1 ))
90-
else
91-
CMAKE_JOBS=$(( $(nproc) - 1 ))
92-
fi
93-
cmake --build . -j "${CMAKE_JOBS}"
94-
95-
# Copy the flatc binary to conda path
96-
EXEC_PATH=$(dirname "$(which python)")
97-
cp flatc "${EXEC_PATH}"
98-
99-
popd || return
100-
}
101-
10283
build_executorch_runner_buck2() {
10384
# Build executorch runtime with retry as this step is flaky on macos CI
10485
retry buck2 build //examples/portable/executor_runner:executor_runner
@@ -111,9 +92,14 @@ build_executorch_runner_cmake() {
11192
mkdir "${CMAKE_OUTPUT_DIR}"
11293

11394
pushd "${CMAKE_OUTPUT_DIR}" || return
95+
if [[ $1 == "Debug" ]]; then
96+
CXXFLAGS="-fsanitize=address,undefined"
97+
else
98+
CXXFLAGS=""
99+
fi
114100
# This command uses buck2 to gather source files and buck2 could crash flakily
115101
# on MacOS
116-
retry cmake -DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}" -DCMAKE_BUILD_TYPE="${1:-Release}" ..
102+
CXXFLAGS="$CXXFLAGS" retry cmake -DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}" -DCMAKE_BUILD_TYPE="${1:-Release}" ..
117103
popd || return
118104

119105
if [ "$(uname)" == "Darwin" ]; then

.ci/scripts/wheel/test_macos.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
test_base.ModelTest(
1515
model=Model.Mv3,
1616
backend=Backend.XnnpackQuantizationDelegation,
17-
)
17+
),
18+
# Enable this once CoreML is suppported out-of-the-box
19+
# https://github.com/pytorch/executorch/issues/9019
20+
# test_base.ModelTest(
21+
# model=Model.Mv3,
22+
# backend=Backend.CoreMlTest,
23+
# )
1824
]
1925
)

.github/workflows/apple.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
- build/build_apple_frameworks.sh
1515
- build/build_apple_llm_demo.sh
1616
- build/create_frameworks.sh
17-
- build/test_ios_ci.sh
17+
- .ci/scripts/test_ios_ci.sh
1818
- examples/demo-apps/apple_ios/**
1919
- extension/apple/**
2020
- extension/benchmark/apple/**
@@ -75,7 +75,7 @@ jobs:
7575
7676
# Build and test iOS Demo App
7777
PYTHON_EXECUTABLE=python ${CONDA_RUN} --no-capture-output \
78-
build/test_ios_ci.sh "${ARTIFACTS_DIR_NAME}"
78+
.ci/scripts/test_ios_ci.sh "${ARTIFACTS_DIR_NAME}"
7979
8080
# Upload the test demo app to S3
8181
upload-demo-ios:

.github/workflows/trunk.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ jobs:
176176
id-token: write
177177
contents: read
178178
with:
179-
runner: linux.2xlarge
179+
runner: linux.2xlarge.memory
180180
docker-image: executorch-ubuntu-22.04-arm-sdk
181181
submodules: 'true'
182182
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
@@ -206,7 +206,7 @@ jobs:
206206
id-token: write
207207
contents: read
208208
with:
209-
runner: linux.2xlarge
209+
runner: linux.2xlarge.memory
210210
docker-image: executorch-ubuntu-22.04-arm-sdk
211211
submodules: 'true'
212212
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}

CMakeLists.txt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ endif()
460460
# tools like `flatc`, along with example executables like `executor_runner` and
461461
# libraries that it uses, like `gflags`. Disabling this can be helpful when
462462
# cross-compiling, but some required tools that would have been built need to be
463-
# provided directly (via, for example, FLATC_EXECUTABLE).
463+
# provided directly.
464464
cmake_dependent_option(
465465
EXECUTORCH_BUILD_HOST_TARGETS "Build host-only targets." ON
466466
"NOT CMAKE_TOOLCHAIN_IOS" OFF
@@ -471,10 +471,9 @@ cmake_dependent_option(
471471
#
472472
cmake_dependent_option(
473473
EXECUTORCH_BUILD_FLATC "Build the flatc executable." ON
474-
"NOT FLATC_EXECUTABLE;EXECUTORCH_BUILD_HOST_TARGETS" OFF
474+
"NOT FLATC_EXECUTABLE" OFF
475475
)
476476

477-
478477
set(FLATBUFFERS_BUILD_FLATC OFF CACHE BOOL "")
479478
set(FLATBUFFERS_BUILD_FLATHASH OFF CACHE BOOL "")
480479
set(FLATBUFFERS_BUILD_FLATLIB OFF CACHE BOOL "")
@@ -507,6 +506,8 @@ if(EXECUTORCH_BUILD_FLATC)
507506
-DFLATBUFFERS_BUILD_TESTS=${FLATBUFFERS_BUILD_TESTS}
508507
-DFLATBUFFERS_INSTALL=${FLATBUFFERS_INSTALL}
509508
-DCMAKE_CXX_FLAGS="-DFLATBUFFERS_MAX_ALIGNMENT=${FLATBUFFERS_MAX_ALIGNMENT}"
509+
# If building for iOS, "unset" these variables to rely on the host (macOS) defaults.
510+
$<$<AND:$<BOOL:${CMAKE_TOOLCHAIN_IOS}>,$<BOOL:$<FILTER:${PLATFORM},EXCLUDE,^MAC>>>:-DCMAKE_OSX_SYSROOT=>
510511
INSTALL_COMMAND ""
511512
BUILD_BYPRODUCTS <BINARY_DIR>/flatc
512513
)
@@ -515,6 +516,8 @@ if(EXECUTORCH_BUILD_FLATC)
515516
# flatbuffers does not use CMAKE_BUILD_TYPE. Internally, the build forces Release
516517
# config, but from CMake's perspective the build type is always Debug.
517518
set(FLATC_EXECUTABLE ${BINARY_DIR}/$<CONFIG>/flatc.exe)
519+
elseif(CMAKE_GENERATOR STREQUAL "Xcode")
520+
set(FLATC_EXECUTABLE ${BINARY_DIR}/$<CONFIG>/flatc)
518521
else()
519522
set(FLATC_EXECUTABLE ${BINARY_DIR}/flatc)
520523
endif()
@@ -528,12 +531,7 @@ if(NOT FLATC_EXECUTABLE)
528531
find_program(FLATC_EXECUTABLE flatc)
529532

530533
if(NOT FLATC_EXECUTABLE)
531-
message(
532-
FATAL_ERROR
533-
"FLATC_EXECUTABLE must be set when EXECUTORCH_BUILD_FLATC is disabled. "
534-
"Note that EXECUTORCH_BUILD_FLATC may be disabled implicitly when "
535-
"cross-compiling or when EXECUTORCH_BUILD_HOST_TARGETS is disabled."
536-
)
534+
message(FATAL_ERROR "FLATC_EXECUTABLE must be set when EXECUTORCH_BUILD_FLATC is disabled.")
537535
endif()
538536
endif()
539537

backends/apple/coreml/scripts/build_tests.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ cmake "$EXECUTORCH_ROOT_PATH" -B"$CMAKE_EXECUTORCH_BUILD_DIR_PATH" \
3232
-DCMAKE_TOOLCHAIN_FILE="$IOS_TOOLCHAIN_PATH" \
3333
-DPLATFORM=MAC_UNIVERSAL \
3434
-DDEPLOYMENT_TARGET=13.0 \
35-
-DFLATC_EXECUTABLE="$(which flatc)" \
3635
-DEXECUTORCH_BUILD_EXECUTOR_RUNNER=OFF \
3736
-DEXECUTORCH_BUILD_XNNPACK=OFF \
3837
-DEXECUTORCH_BUILD_GFLAGS=OFF

backends/apple/mps/runtime/MPSDevice.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ static inline MTLLanguageVersion getMetalLanguageVersion(const id<MTLDevice>& de
2222
// MPS Advanced Indexing needs at least Metal 2.0 (support for Argument Buffers and function constants)
2323
// host_name attribute needs at least Metal 2.2 and ulong needs Metal 2.3 (supported on MacOS 11+)
2424
MTLLanguageVersion languageVersion = MTLLanguageVersion2_3;
25-
#if defined(__MAC_13_0)
26-
if (macOS13Plus) {
27-
languageVersion = MTLLanguageVersion3_0;
25+
if (@available(iOS 16, macOS 13, *)) {
26+
if (macOS13Plus) {
27+
languageVersion = MTLLanguageVersion3_0;
28+
}
2829
}
29-
#endif
3030

3131
ET_CHECK_MSG([device supportsFamily:MTLGPUFamilyMac2], "Missing Metal support for MTLGPUFamilyMac2");
3232
return languageVersion;

backends/apple/mps/runtime/operations/IndexingOps.mm

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -206,25 +206,32 @@
206206

207207
Error
208208
MPSGraphBuilder::mpsScatterOp(NodePtr nodePtr) {
209-
auto graphNode = nodePtr->mpsnode_union_as_MPSScatter();
210-
ET_LOG(
211-
Debug, "%s %d: %d",
212-
__FUNCTION__, graphNode->input1_id(), graphNode->output_id()
213-
);
209+
if (@available(iOS 15.4, macOS 12.3, *)) {
210+
auto graphNode = nodePtr->mpsnode_union_as_MPSScatter();
211+
ET_LOG(
212+
Debug, "%s %d: %d",
213+
__FUNCTION__, graphNode->input1_id(), graphNode->output_id()
214+
);
214215

215-
int64_t dim = graphNode->dim();
216-
MPSGraphTensor* inputTensor = getMPSGraphTensor(graphNode->input1_id());
217-
MPSGraphTensor* indicesTensor = getMPSGraphTensor(graphNode->idx_id());
218-
MPSGraphTensor* updatesTensor = getMPSGraphTensor(graphNode->src_id());
216+
int64_t dim = graphNode->dim();
217+
MPSGraphTensor* inputTensor = getMPSGraphTensor(graphNode->input1_id());
218+
MPSGraphTensor* indicesTensor = getMPSGraphTensor(graphNode->idx_id());
219+
MPSGraphTensor* updatesTensor = getMPSGraphTensor(graphNode->src_id());
219220

220-
_idToMPSGraphTensor[graphNode->output_id()] =
221-
[_mpsGraph scatterAlongAxis:dim
222-
withDataTensor:inputTensor
223-
updatesTensor:updatesTensor
224-
indicesTensor:indicesTensor
225-
mode:MPSGraphScatterModeSet
226-
name:nil];
227-
return Error::Ok;
221+
_idToMPSGraphTensor[graphNode->output_id()] =
222+
[_mpsGraph scatterAlongAxis:dim
223+
withDataTensor:inputTensor
224+
updatesTensor:updatesTensor
225+
indicesTensor:indicesTensor
226+
mode:MPSGraphScatterModeSet
227+
name:nil];
228+
229+
return Error::Ok;
230+
} else {
231+
ET_LOG(Error, "MPS: scatter op is not supported on iOS < 15.4 and macOS < 12.3");
232+
233+
return Error::NotSupported;
234+
}
228235
}
229236

230237

backends/arm/operator_support/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
pool_2d_support,
1212
reduce_sum_support,
1313
right_shift_support,
14+
slice_copy_support,
1415
to_copy_support,
1516
tosa_supported_operators,
1617
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright 2025 Arm Limited and/or its affiliates.
2+
#
3+
# This source code is licensed under the BSD-style license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
7+
import logging
8+
9+
import torch.fx as fx
10+
from executorch.backends.arm.operator_support.tosa_supported_operators import (
11+
register_tosa_support_check,
12+
SupportedTOSAOperatorCheck,
13+
)
14+
from executorch.backends.arm.tosa_specification import TosaSpecification
15+
from executorch.backends.arm.tosa_utils import getNodeArgs
16+
from executorch.exir.dialects._ops import ops as exir_ops
17+
18+
logger = logging.getLogger(__name__)
19+
logger.setLevel(logging.WARNING)
20+
21+
22+
@register_tosa_support_check
23+
class SliceCopySupported(SupportedTOSAOperatorCheck):
24+
targets = [exir_ops.edge.aten.slice_copy.Tensor]
25+
26+
tosa_specs = [
27+
TosaSpecification.create_from_string("TOSA-0.80+BI"),
28+
TosaSpecification.create_from_string("TOSA-0.80+MI"),
29+
]
30+
31+
def is_node_tosa_supported(self, node: fx.Node, tosa_spec: TosaSpecification) -> bool: # type: ignore[override, misc]
32+
if tosa_spec not in self.tosa_specs:
33+
return False
34+
35+
inputs = getNodeArgs(node)
36+
if len(inputs) == 5 and (step := inputs[4].number) != 1:
37+
logging.warning(f"{node.target} with step size of {step} not supported.")
38+
return False
39+
return True

backends/arm/operator_support/tosa_supported_operators.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def register_tosa_support_check(checker: Type[SupportedTOSAOperatorCheck]):
7777
def get_registered_tosa_support_checks(
7878
tosa_spec: TosaSpecification,
7979
) -> list[Type[SupportedTOSAOperatorCheck]]:
80-
8180
if tosa_spec not in _tosa_spec_support:
8281
raise RuntimeError(
8382
f"TOSA specification not valid: {tosa_spec} not in {list(_tosa_spec_support.keys())}"
@@ -186,7 +185,6 @@ def is_node_supported(
186185
exir_ops.edge.aten._softmax.default,
187186
exir_ops.edge.aten.select_copy.int,
188187
exir_ops.edge.aten._log_softmax.default,
189-
exir_ops.edge.aten.slice_copy.Tensor,
190188
exir_ops.edge.aten.sub.Tensor,
191189
exir_ops.edge.aten.tanh.default,
192190
exir_ops.edge.aten.upsample_nearest2d.vec,

backends/arm/operators/op_add.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ def define_node(
4545
# Handle int8 (quantized) and int32
4646
assert inputs[0].dtype in [ts.DType.INT8, ts.DType.INT32]
4747

48+
dim_order = (
49+
inputs[0].dim_order
50+
if len(inputs[0].shape) > len(inputs[1].shape)
51+
else inputs[1].dim_order
52+
)
53+
4854
if inputs[0].dtype == ts.DType.INT8:
4955
rescaled_inputs, scale_back = tqutils.insert_rescale_ops_to_int32(
5056
tosa_graph, inputs, node
@@ -61,13 +67,14 @@ def define_node(
6167
# output.dtype == ts.DType.INT32
6268
add_output = output
6369

70+
input1, input2 = tutils.reshape_for_broadcast(
71+
tosa_graph, rescaled_inputs, dim_order
72+
)
73+
6474
# Do the INT32 Add
6575
tosa_graph.addOperator(
6676
TosaOp.Op().ADD,
67-
[
68-
rescaled_inputs[0].name,
69-
rescaled_inputs[1].name,
70-
],
77+
[input1.name, input2.name],
7178
[add_output.name],
7279
None,
7380
)
@@ -108,10 +115,12 @@ def define_node(
108115
assert inputs[0].dtype == ts.DType.FP32
109116
assert output.dtype == ts.DType.FP32
110117

118+
input1, input2 = tutils.reshape_for_broadcast(tosa_graph, inputs)
119+
111120
# MI lowering
112121
tosa_graph.addOperator(
113122
TosaOp.Op().ADD,
114-
[inputs[0].name, inputs[1].name],
123+
[input1.name, input2.name],
115124
[output.name],
116125
None,
117126
)

0 commit comments

Comments
 (0)