Skip to content

Commit 85bb6c3

Browse files
authored
Merge branch 'main' into jz/update-android-readme
2 parents b05b8ab + 7175ca4 commit 85bb6c3

File tree

27 files changed

+143
-132
lines changed

27 files changed

+143
-132
lines changed

CMakeLists.txt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,33 @@ project(executorch)
4848
# MARK: - Start EXECUTORCH_H12025_BUILD_MIGRATION --------------------------------------------------
4949

5050
include(${PROJECT_SOURCE_DIR}/tools/cmake/common/preset.cmake)
51+
include(${PROJECT_SOURCE_DIR}/tools/cmake/Utils.cmake)
52+
include(CMakeDependentOption)
53+
include(ExternalProject)
5154

5255
if(NOT CMAKE_CXX_STANDARD)
5356
set(CMAKE_CXX_STANDARD 17)
5457
endif()
5558
announce_configured_options(CMAKE_CXX_STANDARD)
5659

60+
if(NOT CMAKE_SYSTEM_PROCESSOR)
61+
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR})
62+
endif()
63+
announce_configured_options(CMAKE_SYSTEM_PROCESSOR)
64+
5765
if(NOT CMAKE_BUILD_TYPE)
5866
set(CMAKE_BUILD_TYPE Debug)
5967
endif()
6068
announce_configured_options(CMAKE_BUILD_TYPE)
6169

70+
if(NOT PYTHON_EXECUTABLE)
71+
resolve_python_executable()
72+
endif()
73+
announce_configured_options(PYTHON_EXECUTABLE)
74+
6275
announce_configured_options(CMAKE_CXX_COMPILER_ID)
6376
announce_configured_options(CMAKE_TOOLCHAIN_FILE)
6477
announce_configured_options(BUCK2)
65-
announce_configured_options(PYTHON_EXECUTABLE)
6678

6779
load_build_preset()
6880
include(${PROJECT_SOURCE_DIR}/tools/cmake/preset/default.cmake)
@@ -72,10 +84,6 @@ print_configured_options()
7284

7385
# MARK: - End EXECUTORCH_H12025_BUILD_MIGRATION ----------------------------------------------------
7486

75-
include(tools/cmake/Utils.cmake)
76-
include(CMakeDependentOption)
77-
include(ExternalProject)
78-
7987
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
8088

8189
# Setup RPATH.
@@ -251,11 +259,6 @@ if(EXECUTORCH_BUILD_TESTS)
251259
include(CTest)
252260
endif()
253261

254-
if(NOT PYTHON_EXECUTABLE)
255-
resolve_python_executable()
256-
endif()
257-
message(STATUS "Using python executable '${PYTHON_EXECUTABLE}'")
258-
259262
# TODO(dbort): Fix these warnings and remove this flag.
260263
set(_common_compile_options -Wno-deprecated-declarations -fPIC)
261264

backends/apple/mps/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ endif()
1818

1919
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
2020

21-
if(NOT PYTHON_EXECUTABLE)
22-
resolve_python_executable()
23-
endif()
24-
2521
set(_common_compile_options -Wno-deprecated-declarations)
2622
set(_common_include_directories ${EXECUTORCH_ROOT}/..)
2723

backends/cadence/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ add_compile_definitions(C10_USING_CUSTOM_GENERATED_MACROS)
3030
if(EXECUTORCH_CADENCE_CPU_RUNNER)
3131
include(${EXECUTORCH_ROOT}/tools/cmake/Codegen.cmake)
3232

33-
if(NOT PYTHON_EXECUTABLE)
34-
resolve_python_executable()
35-
endif()
36-
3733
set(_common_compile_options -Wno-deprecated-declarations -fPIC)
3834

3935
# Find prebuilt libraries. executorch package should contain portable_ops_lib,

backends/cadence/aot/pass_utils.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,34 @@ def nodes_not_adjacent_in_gm(
157157
if node.next.target == succ_target:
158158
return False
159159
return True
160+
161+
162+
def get_arg(
163+
node: torch.fx.Node,
164+
arg_index: int,
165+
kwarg_name: str,
166+
*,
167+
default: torch.fx.node.Argument = None,
168+
) -> torch.fx.node.Argument:
169+
"""
170+
Get the arg at arg_index or kwarg with arg_name of the node. If neither is found
171+
return default.
172+
"""
173+
if arg_index < len(node.args):
174+
return node.args[arg_index]
175+
elif kwarg_name in node.kwargs:
176+
return node.kwargs[kwarg_name]
177+
else:
178+
return default
179+
180+
181+
def set_arg(
182+
node: torch.fx.Node, arg_index: int, kwarg_name: str, value: torch.fx.node.Argument
183+
) -> None:
184+
"""
185+
Set the arg at arg_index if it exists, otherwise set the kwarg.
186+
"""
187+
if arg_index < len(node.args):
188+
node.update_arg(arg_index, value)
189+
else:
190+
node.update_kwarg(kwarg_name, value)

backends/cadence/aot/remove_ops.py

Lines changed: 43 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import torch.fx
2626
from executorch.backends.cadence.aot.pass_utils import (
2727
CadencePassAttribute,
28+
get_arg,
2829
register_cadence_pass,
30+
set_arg,
2931
)
3032

3133
from executorch.backends.cadence.aot.simplify_ops import SimplifySliceOpPass
@@ -37,7 +39,7 @@
3739
from executorch.exir.pass_manager import PassManager, PassType
3840
from executorch.exir.passes import dead_code_elimination_pass
3941
from executorch.exir.passes.spec_prop_pass import SpecPropPass
40-
from torch.fx.node import Argument
42+
from torch.fx.node import Argument, Node
4143

4244

4345
@register_cadence_pass(CadencePassAttribute(opt_level=0))
@@ -771,65 +773,52 @@ def remove_branched(
771773

772774

773775
class RemoveCatFromSliceCopyPass(ExportPass):
774-
def _remove_unused_cat( # noqa: C901
775-
self, graph_module: torch.fx.GraphModule
776-
) -> None:
777-
slice_copy_nodes = [
778-
node
779-
for node in graph_module.graph.nodes
780-
if node.target == exir_ops.edge.aten.slice_copy.Tensor
781-
]
782-
for slice_copy_node in slice_copy_nodes:
783-
slice_dim, start_idx, end_idx, step = 0, 0, float("inf"), 1
784-
input_node, *other_args = slice_copy_node.args
785-
if len(other_args) >= 1:
786-
slice_dim = other_args[0]
787-
if len(other_args) >= 2:
788-
start_idx = other_args[1]
789-
if len(other_args) >= 3:
790-
end_idx = other_args[2]
791-
if len(other_args) >= 4:
792-
step = other_args[3]
793-
if step != 1:
794-
continue
795-
slice_copy_dtype = slice_copy_node.meta["val"].dtype
796-
if input_node.target != exir_ops.edge.aten.cat.default:
797-
continue
798-
cat_dtype = input_node.meta["val"].dtype
799-
if slice_copy_dtype != cat_dtype:
776+
"""
777+
Simplifies cat->slice_copy chains where one of the cat inputs can be directly passed
778+
to the slice_copy.
779+
"""
780+
781+
def _remove_unused_cat(self, graph_module: torch.fx.GraphModule) -> None:
782+
for slice_copy_node in graph_module.graph.find_nodes(
783+
op="call_function", target=exir_ops.edge.aten.slice_copy.Tensor
784+
):
785+
cat_node = cast(Node, get_arg(slice_copy_node, 0, "input"))
786+
slice_dim = cast(int, get_arg(slice_copy_node, 1, "dim", default=0))
787+
start_idx = cast(int, get_arg(slice_copy_node, 2, "start", default=None))
788+
end_idx = cast(int, get_arg(slice_copy_node, 3, "end", default=None))
789+
step = cast(int, get_arg(slice_copy_node, 4, "step", default=1))
790+
791+
if cat_node.target != exir_ops.edge.aten.cat.default or step != 1:
800792
continue
801-
cat_dim = input_node.args[1:]
802-
if len(cat_dim) == 0:
803-
cat_dim = 0
793+
794+
# Make sure cat and slice happens on the same dimension.
795+
cat_dim = cast(Node, get_arg(cat_node, 1, "dim", default=0))
804796
if cat_dim != slice_dim:
805797
continue
806-
cat_output_shape = input_node.meta["val"].shape
807-
start_idx = (
808-
cat_output_shape[cat_dim] + start_idx if start_idx < 0 else start_idx
809-
)
810-
end_idx = (
811-
cat_output_shape[cat_dim]
812-
if end_idx > cat_output_shape[cat_dim]
813-
else end_idx
814-
)
815-
base_idx = 0
816-
cat_input_to_keep = None
817-
for cat_input_node in input_node.args[0]:
818-
cat_input_dtype = cat_input_node.meta["val"].dtype
819-
if slice_copy_dtype != cat_input_dtype:
820-
continue
798+
799+
# Canonicalize slice indices.
800+
cat_output_shape = cat_node.meta["val"].shape
801+
if start_idx is None:
802+
start_idx = 0
803+
elif start_idx < 0:
804+
start_idx += cat_output_shape[cat_dim]
805+
if end_idx is None or end_idx > cat_output_shape[cat_dim]:
806+
end_idx = cat_output_shape[cat_dim]
807+
elif end_idx < 0:
808+
end_idx += cat_output_shape[cat_dim]
809+
810+
offset = 0
811+
for cat_input_node in cast(List[Node], get_arg(cat_node, 0, "tensors")):
821812
cat_input_shape = cat_input_node.meta["val"].shape
822813

823-
# check if the slice range overlaps with the cat range
824-
if (
825-
base_idx <= start_idx
826-
and end_idx <= list(cat_input_shape)[cat_dim] + base_idx
827-
):
828-
cat_input_to_keep = cat_input_node
814+
# Check if the slice range overlaps with the cat input range.
815+
if offset <= start_idx and end_idx <= offset + cat_input_shape[cat_dim]:
816+
slice_copy_node.replace_input_with(cat_node, cat_input_node)
817+
set_arg(slice_copy_node, 2, "start", start_idx - offset)
818+
set_arg(slice_copy_node, 3, "end", end_idx - offset)
829819
break
830-
base_idx += list(cat_input_shape)[cat_dim]
831-
if cat_input_to_keep is not None:
832-
slice_copy_node.replace_input_with(input_node, cat_input_to_keep)
820+
821+
offset += cat_input_shape[cat_dim]
833822

834823
def call(self, graph_module: torch.fx.GraphModule) -> PassResult:
835824
self._remove_unused_cat(graph_module)

backends/cadence/aot/tests/test_remove_ops_passes.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,3 +864,30 @@ def forward(self, x, y):
864864

865865
# Ensure both cat nodes were removed
866866
self.assertEqual(count_node(graph_module, exir_ops.edge.aten.cat.default), 0)
867+
868+
def test_remove_cat_from_slice_copy_second_input(self) -> None:
869+
builder = GraphBuilder()
870+
x = builder.placeholder("x", torch.randn(2, 4))
871+
y = builder.placeholder("y", torch.randn(2, 4))
872+
cat = builder.call_operator(
873+
op=exir_ops.edge.aten.cat.default,
874+
args=((x, y), 1),
875+
)
876+
slice_copy = builder.call_operator(
877+
op=exir_ops.edge.aten.slice_copy.Tensor,
878+
args=(cat, 1, 5, 7, 1),
879+
)
880+
builder.output([slice_copy])
881+
graph_module = builder.get_graph_module()
882+
883+
inputs = (torch.randn(2, 4), torch.randn(2, 4))
884+
expected_outputs = graph_module(*inputs)[0]
885+
886+
p = RemoveCatFromSliceCopyPass()
887+
graph_module = cast(PassResult, p(graph_module)).graph_module
888+
889+
# Cat should be removed.
890+
self.assertEqual(count_node(graph_module, exir_ops.edge.aten.cat.default), 0)
891+
892+
# Output should remain the same.
893+
self.assertTrue(torch.equal(graph_module(*inputs)[0], expected_outputs))

backends/cadence/fusion_g3/operators/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ endif()
1414
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
1515
include(${EXECUTORCH_ROOT}/tools/cmake/Codegen.cmake)
1616

17-
if(NOT PYTHON_EXECUTABLE)
18-
resolve_python_executable()
19-
endif()
20-
2117
# ATen compliant ops that are needed to run this model.
2218
set(_aten_ops__srcs
2319
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/activation_ops_util.cpp"

backends/cadence/hifi/operators/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ endif()
1414
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
1515
include(${EXECUTORCH_ROOT}/tools/cmake/Codegen.cmake)
1616

17-
if(NOT PYTHON_EXECUTABLE)
18-
resolve_python_executable()
19-
endif()
20-
2117
# ATen compliant ops that are needed to run this model.
2218
set(_aten_ops__srcs
2319
"${EXECUTORCH_ROOT}/backends/cadence/hifi/operators/op_add.cpp"

backends/cadence/reference/operators/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ endif()
1414
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
1515
include(${EXECUTORCH_ROOT}/tools/cmake/Codegen.cmake)
1616

17-
if(NOT PYTHON_EXECUTABLE)
18-
resolve_python_executable()
19-
endif()
20-
2117
# ATen compliant ops that are needed to run this model.
2218
set(_aten_ops__srcs
2319
"${CMAKE_CURRENT_SOURCE_DIR}/op_add.cpp"

backends/cortex_m/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ endif()
2323
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
2424
include(${EXECUTORCH_ROOT}/tools/cmake/Codegen.cmake)
2525

26-
if(NOT PYTHON_EXECUTABLE)
27-
resolve_python_executable()
28-
endif()
29-
3026
# Cortex-M ops kernel sources
3127
set(_cortex_m_kernels__srcs
3228
${CMAKE_CURRENT_SOURCE_DIR}/ops/op_quantize_per_tensor.cpp

backends/vulkan/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ if(NOT RUNTIME_PATH)
2424
set(RUNTIME_PATH ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
2525
endif()
2626

27-
if(NOT PYTHON_EXECUTABLE)
28-
set(PYTHON_EXECUTABLE python3)
29-
endif()
30-
3127
# Include this file to access target_link_options_shared_lib This is required to
3228
# provide access to target_link_options_shared_lib which allows libraries to be
3329
# linked with the --whole-archive flag. This is required for libraries that

backends/vulkan/test/op_tests/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ find_library(LIB_TORCH torch HINTS ${TORCH_INSTALL_PREFIX}/lib)
4545
find_library(LIB_TORCH_CPU torch_cpu HINTS ${TORCH_INSTALL_PREFIX}/lib)
4646
find_library(LIB_C10 c10 HINTS ${TORCH_INSTALL_PREFIX}/lib)
4747

48-
if(NOT PYTHON_EXECUTABLE)
49-
set(PYTHON_EXECUTABLE python3)
50-
endif()
51-
5248
# Third party include paths
5349

5450
set(VULKAN_THIRD_PARTY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../third-party)

backends/xnnpack/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ endif()
2525

2626
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
2727

28-
if(NOT PYTHON_EXECUTABLE)
29-
resolve_python_executable()
30-
endif()
31-
3228
# NB: Enabling this will serialize execution of delegate instances Keeping this
3329
# OFF by default to maintain existing behavior, to be revisited.
3430
option(EXECUTORCH_XNNPACK_SHARED_WORKSPACE

configurations/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ endif()
1818

1919
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
2020

21-
if(NOT PYTHON_EXECUTABLE)
22-
resolve_python_executable()
23-
endif()
24-
2521
set(_common_compile_options -Wno-deprecated-declarations)
2622

2723
include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)

examples/models/llama/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ Note for Mac users: There's a known linking issue with Xcode 15.1. Refer to the
295295
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON \
296296
-DEXECUTORCH_BUILD_XNNPACK=ON \
297297
-DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON \
298+
-DSUPPORT_REGEX_LOOKAHEAD=ON
298299
-Bcmake-out/examples/models/llama \
299300
examples/models/llama
300301
@@ -353,6 +354,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
353354
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON \
354355
-DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON \
355356
-DEXECUTORCH_BUILD_KERNELS_CUSTOM=ON \
357+
-DSUPPORT_REGEX_LOOKAHEAD=ON
356358
-Bcmake-out-android/examples/models/llama \
357359
examples/models/llama
358360

examples/models/qwen3/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ cmake-out/examples/models/llama/llama_main
8686
```
8787

8888
To run the model on an example iOS or Android app, see the Llama README's [Step 5: Build Mobile apps](../llama/README.md#step-5-build-mobile-apps) section.
89+
90+
### FAQ
91+
For more help with exporting or running this model, feel free to ask in our [discord channel](https://lnkd.in/gWCM4ViK).

extension/flat_tensor/test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ add_custom_command(
2222
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ModuleAddMulProgram.pte"
2323
"${CMAKE_CURRENT_BINARY_DIR}/ModuleAddMulProgram.ptd"
2424
COMMAND
25-
python -m test.models.export_program --modules "ModuleAddMul"
25+
${PYTHON_EXECUTABLE} -m test.models.export_program --modules "ModuleAddMul"
2626
--external-constants --outdir "${CMAKE_CURRENT_BINARY_DIR}" 2> /dev/null
2727
WORKING_DIRECTORY ${EXECUTORCH_ROOT}
2828
)

0 commit comments

Comments
 (0)