Skip to content

Commit 9089532

Browse files
Merge branch 'main' into add-logical-binary-ops-to-executorch
2 parents 7144767 + 51901f3 commit 9089532

File tree

56 files changed

+594
-589
lines changed

Some content is hidden

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

56 files changed

+594
-589
lines changed

.ci/docker/common/install_java.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
set -ex
9+
10+
apt-get update
11+
12+
apt-get install -y --no-install-recommends openjdk-17-jdk

.ci/docker/ubuntu/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ ARG BUCK2_VERSION
3030
COPY ./common/install_buck.sh install_buck.sh
3131
RUN bash ./install_buck.sh && rm install_buck.sh
3232

33+
# Install java
34+
COPY ./common/install_java.sh install_java.sh
35+
RUN bash ./install_java.sh && rm install_java.sh
36+
3337
# Setup user
3438
COPY ./common/install_user.sh install_user.sh
3539
RUN bash ./install_user.sh && rm install_user.sh

.github/workflows/doc-build.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ jobs:
6868
make html
6969
cd ..
7070
71+
# Build javadoc:
72+
cd extension/android
73+
./gradlew javadoc
74+
cp -rf build/docs/javadoc "${RUNNER_DOCS_DIR}"
75+
cd ../..
76+
7177
# If it's main branch, add noindex tag to all .html files to exclude from Google Search indexing.
7278
echo "GitHub Ref: ${GITHUB_REF}"
7379
if [[ "${{ github.ref }}" == 'refs/heads/main' ]]; then

CODEOWNERS

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/backends/vulkan @SS-JIA
1616
/backends/xnnpack @digantdesai @mcr229
1717

18-
/build @GregoryComer @dbort @kirklandsign
18+
/build @GregoryComer @kirklandsign
1919

2020
/codegen @larryliu0820 @lucylq
2121

@@ -47,32 +47,32 @@
4747
/extension/apple @shoumikhin
4848
/extension/aten_util @JacobSzwejbka
4949
/extension/benchmark @tarun292
50-
/extension/data_loader @JacobSzwejbka @lucylq @dbort
51-
/extension/evalue_util @GregoryComer @dbort
50+
/extension/data_loader @JacobSzwejbka @lucylq
51+
/extension/evalue_util @GregoryComer
5252
/extension/export_util @kimishpatel
5353
/extension/flat_tensor @lucylq
5454
/extension/gguf_util @larryliu0820
5555
/extension/kernel_util @kimishpatel @manuelcandales
5656
/extension/llm @jackzhxng @iseeyuan @larryliu0820
57-
/extension/memory_allocator @JacobSzwejbka @dbort
57+
/extension/memory_allocator @JacobSzwejbka
5858
/extension/module @shoumikhin
5959
/extension/parallel @kimishpatel
6060
/extension/pybindings @JacobSzwejbka @larryliu0820
6161
/extension/pytree @JacobSzwejbka
62-
/extension/runner_util @dbort
62+
# /extension/runner_util @dbort
6363
/extension/tensor @shoumikhin
64-
/extension/testing_util @dbort
64+
# /extension/testing_util @dbort
6565
/extension/threadpool @kimishpatel
6666
/extension/training @JacobSzwejbka
6767

6868
/kernels @manuelcandales
6969

7070
/profiler @tarun292 @Gasoonjia
7171

72-
/runtime @dbort @JacobSzwejbka @lucylq
72+
/runtime @JacobSzwejbka @lucylq
7373
/runtime/backend @cccclai
7474

75-
/schema @dbort @JacobSzwejbka @lucylq
75+
/schema @JacobSzwejbka @lucylq
7676

7777
/scripts @GregoryComer
7878

backends/apple/coreml/test/test_coreml_partitioner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def forward(self, q, k, v, mask):
117117
v = torch.randn(batch_size, n_heads, max_seq_length, embedding_dim)
118118
mask = torch.randn(seq_len, max_seq_length)
119119
example_inputs = (q, k, v, mask)
120-
ep = torch.export.export(model, example_inputs)
120+
ep = torch.export.export(model, example_inputs, strict=True)
121121
coreml_partitioner = CoreMLPartitioner()
122122

123123
# Using to_edge_transform_and_lower, we expect SDPA will be preserved and show up in delegated graph

backends/apple/mps/runtime/MPSBackend.mm

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ bool is_available() const override {
4343
BackendInitContext& context,
4444
FreeableBuffer* processed,
4545
ArrayRef<CompileSpec> compile_specs) const override {
46-
auto executor = ET_ALLOCATE_INSTANCE_OR_RETURN_ERROR(
47-
context.get_runtime_allocator(), mps::delegate::MPSExecutor);
46+
auto executor = context.get_runtime_allocator()->allocateInstance<mps::delegate::MPSExecutor>();
47+
if (executor == nullptr) {
48+
return Error::MemoryAllocationFailed;
49+
}
50+
4851
// NOTE: Since we use placement new and since this type is not trivially
4952
// destructible, we must call the destructor manually in destroy().
5053
new (executor) mps::delegate::MPSExecutor;

backends/arm/runtime/EthosUBackend.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,11 @@ class EthosUBackend final : public ::executorch::runtime::BackendInterface {
120120
}
121121

122122
MemoryAllocator* allocator = context.get_runtime_allocator();
123-
ExecutionHandle* handle =
124-
ET_ALLOCATE_INSTANCE_OR_RETURN_ERROR(allocator, ExecutionHandle);
123+
ExecutionHandle* handle = allocator->allocateInstance<ExecutionHandle>();
124+
if (handle == nullptr) {
125+
return Error::MemoryAllocationFailed;
126+
}
127+
125128
handle->processed = processed;
126129

127130
// Return the same buffer we were passed - this data will be

backends/cadence/aot/remove_ops.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,72 @@ def remove_branched(
807807
user.replace_all_uses_with(node.args[0])
808808

809809

810+
class RemoveCatFromSliceCopyPass(ExportPass):
811+
def _remove_unused_cat(self, graph_module: torch.fx.GraphModule) -> None:
812+
slice_copy_nodes = [
813+
node
814+
for node in graph_module.graph.nodes
815+
if node.target == exir_ops.edge.aten.slice_copy.Tensor
816+
]
817+
for slice_copy_node in slice_copy_nodes:
818+
slice_dim, start_idx, end_idx, step = 0, 0, float("inf"), 1
819+
input_node, *other_args = slice_copy_node.args
820+
if len(other_args) >= 1:
821+
slice_dim = other_args[0]
822+
if len(other_args) >= 2:
823+
start_idx = other_args[1]
824+
if len(other_args) >= 3:
825+
end_idx = other_args[2]
826+
if len(other_args) >= 4:
827+
step = other_args[3]
828+
if step != 1:
829+
continue
830+
slice_copy_dtype = slice_copy_node.meta["val"].dtype
831+
if input_node.target != exir_ops.edge.aten.cat.default:
832+
continue
833+
cat_dtype = input_node.meta["val"].dtype
834+
if slice_copy_dtype != cat_dtype:
835+
continue
836+
cat_dim = input_node.args[1:]
837+
if len(cat_dim) == 0:
838+
cat_dim = 0
839+
if cat_dim != slice_dim:
840+
continue
841+
cat_output_shape = input_node.meta["val"].shape
842+
start_idx = (
843+
cat_output_shape[cat_dim] + start_idx if start_idx < 0 else start_idx
844+
)
845+
end_idx = (
846+
cat_output_shape[cat_dim]
847+
if end_idx > cat_output_shape[cat_dim]
848+
else end_idx
849+
)
850+
base_idx = 0
851+
cat_input_to_keep = None
852+
for cat_input_node in input_node.args[0]:
853+
cat_input_dtype = cat_input_node.meta["val"].dtype
854+
if slice_copy_dtype != cat_input_dtype:
855+
continue
856+
cat_input_shape = cat_input_node.meta["val"].shape
857+
858+
# check if the slice range overlaps with the cat range
859+
if (
860+
base_idx <= start_idx
861+
and end_idx <= list(cat_input_shape)[cat_dim] + base_idx
862+
):
863+
cat_input_to_keep = cat_input_node
864+
break
865+
base_idx += list(cat_input_shape)[cat_dim]
866+
if cat_input_to_keep is not None:
867+
slice_copy_node.replace_input_with(input_node, cat_input_to_keep)
868+
869+
def call(self, graph_module: torch.fx.GraphModule) -> PassResult:
870+
self._remove_unused_cat(graph_module)
871+
graph_module.recompile()
872+
graph_module.graph.eliminate_dead_code()
873+
return super().call(graph_module)
874+
875+
810876
# The following class consolidates functions to remove ops that are redundant
811877
# in Jarvis. Currently, each function in this class iterates over each node of
812878
# the graph module once. In future, we could consolidate them into a monolithic

backends/cadence/aot/tests/test_remove_ops_passes.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from executorch.backends.cadence.aot.remove_ops import (
2323
RemoveAliasCopyOpPass,
2424
RemoveBranchedQuantDequant,
25+
RemoveCatFromSliceCopyPass,
2526
RemoveCloneOpPass,
2627
RemoveContiguousOpPass,
2728
RemoveDetachCopyPass,
@@ -741,3 +742,54 @@ def forward(self, x):
741742
},
742743
)
743744
)
745+
746+
def test_remove_cat_from_slice_copy_all_removal(self) -> None:
747+
class M(torch.nn.Module):
748+
def __init__(self):
749+
super().__init__()
750+
751+
def forward(self, x, y):
752+
x1 = torch.cat((x, y), 0) # (2, 4)
753+
return torch.slice_copy(x1, dim=0, start=0, end=1)
754+
755+
inputs = tuple(torch.randn(2, 4) for _ in range(2))
756+
graph_module = export_to_edge(M(), inputs).exported_program().graph_module
757+
p = RemoveCatFromSliceCopyPass()
758+
graph_module = cast(PassResult, p(graph_module)).graph_module
759+
760+
# Ensure both cat nodes were removed
761+
self.assertEqual(count_node(graph_module, exir_ops.edge.aten.cat.default), 0)
762+
763+
def test_remove_cat_from_slice_copy_no_removal(self) -> None:
764+
class M(torch.nn.Module):
765+
def __init__(self):
766+
super().__init__()
767+
768+
def forward(self, x, y):
769+
x1 = torch.cat((x, y), 0) # (2, 4)
770+
return torch.slice_copy(x1, dim=0, start=0, end=3)
771+
772+
inputs = tuple(torch.randn(2, 4) for _ in range(2))
773+
graph_module = export_to_edge(M(), inputs).exported_program().graph_module
774+
p = RemoveCatFromSliceCopyPass()
775+
graph_module = cast(PassResult, p(graph_module)).graph_module
776+
777+
# Ensure both cat nodes were removed
778+
self.assertEqual(count_node(graph_module, exir_ops.edge.aten.cat.default), 1)
779+
780+
def test_remove_cat_from_slice_copy_zero_range(self) -> None:
781+
class M(torch.nn.Module):
782+
def __init__(self):
783+
super().__init__()
784+
785+
def forward(self, x, y):
786+
x1 = torch.cat((x, y), 0) # (2, 4)
787+
return torch.slice_copy(x1, dim=0, start=0, end=0)
788+
789+
inputs = tuple(torch.randn(2, 4) for _ in range(2))
790+
graph_module = export_to_edge(M(), inputs).exported_program().graph_module
791+
p = RemoveCatFromSliceCopyPass()
792+
graph_module = cast(PassResult, p(graph_module)).graph_module
793+
794+
# Ensure both cat nodes were removed
795+
self.assertEqual(count_node(graph_module, exir_ops.edge.aten.cat.default), 0)

backends/mediatek/runtime/NeuronBackend.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,12 @@ Result<DelegateHandle*> NeuronBackend::init(
6868
processed->size());
6969

7070
MemoryAllocator* runtime_allocator = context.get_runtime_allocator();
71-
NeuronExecuTorchDelegate* delegate = ET_ALLOCATE_INSTANCE_OR_RETURN_ERROR(
72-
runtime_allocator, NeuronExecuTorchDelegate);
71+
NeuronExecuTorchDelegate* delegate =
72+
runtime_allocator->allocateInstance<NeuronExecuTorchDelegate>();
73+
if (delegate == nullptr) {
74+
return Error::MemoryAllocationFailed;
75+
}
76+
7377
new (delegate) NeuronExecuTorchDelegate();
7478

7579
if (delegate == nullptr) {

0 commit comments

Comments
 (0)