Skip to content

Commit ec35956

Browse files
committed
Update base for Update on "[flat_tensor] Persist FreeableBuffers of external constants in method"
## Problem Currently, the FlatTensorDataMap persists tensors, and returns a FreeableBuffer with an empty free function. The NamedDataMap should not persist data, as most cases (eg. delegate) will want it to be freed. Ownership should be on the caller; `get_data` returns a FreeableBuffer that 'owns' the data. The FreeableBuffer in turn is owned by the caller. NOTE: this doesn't support the case where we want to share plain tensors between methods/pte files at runtime. A custom NDM could support that use-case. ## This diff: 1. Introduces a 'NamedData' struct to method.h. This holds a key and a FreeeableBuffer. 2. Iterate over all the flatbuffer tensors to count the constants tagged with EXTERNAL. NOTE: this will increase load time for all users. Potentially allocate chunks of 16 and use a linked list to store external constants, or store this number in PTE file. 3. Allocate space for num_external_constants using the method allocator. 4. Iterate over all flatbuffer tensors and use the named_data_map to resolve EXTERNAL tensors into the array of NamedData. 5. Pass the resolved external constants to tensor_parser, along with NDM (used for mutable external tensors). 6. Resolved external tensors are stored inside method. They are freed when the method is destructed. Some notes: https://docs.google.com/document/d/1_PBi4JgODuClUPD4PCUWrKNjyUH54zOUHGUJ3QHDNes/edit?tab=t.0#heading=h.blsvwraxss7g Differential Revision: [D69477027](https://our.internmc.facebook.com/intern/diff/D69477027/) [ghstack-poisoned]
2 parents c93d653 + bc497a0 commit ec35956

File tree

94 files changed

+1155
-646
lines changed

Some content is hidden

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

94 files changed

+1155
-646
lines changed

CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ cmake_dependent_option(
245245
)
246246

247247
if(EXECUTORCH_BUILD_EXTENSION_FLAT_TENSOR)
248-
set(EXECUTORCH_BUILF_EXTENSION_DATA_LOADER ON)
248+
set(EXECUTORCH_BUILD_EXTENSION_DATA_LOADER ON)
249249
endif()
250250

251251
if(EXECUTORCH_BUILD_EXTENSION_TRAINING)
@@ -348,6 +348,7 @@ if(EXECUTORCH_BUILD_PTHREADPOOL)
348348
endif()
349349

350350
if(EXECUTORCH_BUILD_TESTS)
351+
set(EXECUTORCH_BUILD_EXTENSION_FLAT_TENSOR ON)
351352
include(CTest)
352353
endif()
353354

@@ -373,7 +374,7 @@ if(NOT "${_repo_dir_name}" STREQUAL "executorch")
373374
"fix for this restriction."
374375
)
375376
endif()
376-
set(_common_include_directories ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/runtime/core/portable_type)
377+
set(_common_include_directories ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/runtime/core/portable_type/c10)
377378

378379
#
379380
# The `_<target>_srcs` lists are defined by including ${EXECUTORCH_SRCS_FILE}.

backends/apple/coreml/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ target_include_directories(
134134
coremldelegate PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/runtime/util
135135
)
136136
target_include_directories(coremldelegate PRIVATE ${EXECUTORCH_ROOT}/..)
137-
target_include_directories(coremldelegate PRIVATE ${EXECUTORCH_ROOT}/runtime/core/portable_type)
137+
target_include_directories(coremldelegate PRIVATE ${EXECUTORCH_ROOT}/runtime/core/portable_type/c10)
138138
target_compile_definitions(coremldelegate PRIVATE C10_USING_CUSTOM_GENERATED_MACROS)
139139
target_link_libraries(coremldelegate PRIVATE executorch_core)
140140

backends/apple/coreml/runtime/workspace/executorchcoreml.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@
922922
"$(SRCROOT)/../kvstore",
923923
"$(SRCROOT)/../inmemoryfs",
924924
"$(SRCROOT)/../include",
925-
"$(SRCROOT)/../include/executorch/runtime/core/portable_type",
925+
"$(SRCROOT)/../include/executorch/runtime/core/portable_type/c10",
926926
"$(SRCROOT)/../sdk",
927927
"$(SRCROOT)/../util",
928928
"$(SRCROOT)/../../third-party/nlohmann_json/single_include",
@@ -954,7 +954,7 @@
954954
"$(SRCROOT)/../kvstore",
955955
"$(SRCROOT)/../inmemoryfs",
956956
"$(SRCROOT)/../include",
957-
"$(SRCROOT)/../include/executorch/runtime/core/portable_type",
957+
"$(SRCROOT)/../include/executorch/runtime/core/portable_type/c10",
958958
"$(SRCROOT)/../sdk",
959959
"$(SRCROOT)/../util",
960960
"$(SRCROOT)/../../third-party/nlohmann_json/single_include",

backends/arm/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2023 Arm Limited and/or its affiliates.
1+
# Copyright 2023, 2025 Arm Limited and/or its affiliates.
22
#
33
# This source code is licensed under the BSD-style license found in the
44
# LICENSE file in the root directory of this source tree.
@@ -14,15 +14,15 @@ endif()
1414

1515
include(${EXECUTORCH_ROOT}/build/Utils.cmake)
1616

17-
set(_common_include_directories ${EXECUTORCH_ROOT}/.. ${EXECUTORCH_ROOT}/runtime/core/portable_type)
17+
set(_common_include_directories ${EXECUTORCH_ROOT}/.. ${EXECUTORCH_ROOT}/runtime/core/portable_type/c10)
1818
add_compile_definitions(C10_USING_CUSTOM_GENERATED_MACROS)
1919

2020
# Third-party folder and Ethos-U driver inclued
2121
set(THIRD_PARTY_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/third-party")
2222
set(DRIVER_ETHOSU_INCLUDE_DIR "${THIRD_PARTY_ROOT}/ethos-u-core-driver/include")
2323
include_directories(${DRIVER_ETHOSU_INCLUDE_DIR})
2424

25-
set(_arm_baremetal_sources backends/arm/runtime/ArmBackendEthosU.cpp
25+
set(_arm_baremetal_sources backends/arm/runtime/EthosUBackend.cpp
2626
backends/arm/runtime/VelaBinStream.cpp
2727
)
2828
list(TRANSFORM _arm_baremetal_sources PREPEND "${EXECUTORCH_ROOT}/")

backends/arm/README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ethos-u-vela compilation stack. which follows the fully AoT flow.
1515
## Layout
1616

1717
Export:
18-
- `arm_backend.py` - Main entrypoint for the ArmPartitioner and ArmBackend. For more information see the section on
18+
- `ethosu_backend.py` - Main entrypoint for the EthosUBackend. For more information see the section on
1919
[Arm Backend Architecture](#arm-backend-architecture). For examples of use see `executorch/examples/arm`.
2020
- `tosa_mapping.py` - utilities for mapping edge dialect to TOSA
2121
- `tosa_quant_utils.py` - utilities for mapping quantization information to TOSA encoding
@@ -29,11 +29,11 @@ Passes:
2929
- `*_pass.py` - Compiler passes derived from ExportPass
3030

3131
Quantization:
32-
- `arm_quantizer.py` - Quantizer for Arm backend
32+
- `arm_quantizer.py` - Quantizers for Arm backend. Contains the EthosUQuantizer which inherits from the TOSAQuantizer
3333
- `arm_quantizer_utils.py` - Utilities for quantization
3434

3535
Runtime:
36-
- `runtime/ArmBackendEthosU.cpp` - The Arm backend implementation of the ExecuTorch runtime backend (BackendInterface) for Ethos-U
36+
- `runtime/ArmEthosUBackend.cpp` - The Arm backend implementation of the ExecuTorch runtime backend (BackendInterface) for Ethos-U
3737

3838
Other:
3939
- `third-party/` - Dependencies on other code - in particular the TOSA serialization_lib for compiling to TOSA and the ethos-u-core-driver for the bare-metal backend supporting Ethos-U
@@ -177,6 +177,7 @@ create an issue on [github](https://www.github.com/pytorch/executorch/issues).
177177
# Arm Backend Architecture
178178

179179
The broad principle with the Arm backend implemention for ExecuTorch is to support multiple Arm devices and device configurations through a largely Homogeneous flow with maximal sharing of class logic.
180+
The EthosUBackend is currently the one user facing API that target the Ethos-U55 and Ethos-U85 hardware IP. It is using the TOSABackend under the hood to share code and functionality, but also to separate testing possibilities to the TOSA flow itself.
180181

181182
In practice for compilation, this means that the flow goes via [Arm TOSA](https://www.mlplatform.org/tosa/tosa_spec.html) to produce a common IR and quantization behaviour compatible with our various IP, and typically, device-specific backends to further lower to a device specific binary which can happen ahead of time (within the Python development flow) or at runtime (during a JIT compilation stage).
182183

@@ -185,22 +186,22 @@ In practice for the runtime, this means we will share common runtime backend fun
185186

186187
## Arm Backend Status and Maturity
187188

188-
The Arm Backend should be considered a prototype quality at this point, likely subject to significant change and improvement, and with a limited coverage of functionality. We are actively developing this codebase.
189+
The Arm EthosU Backend should be considered a prototype quality at this point, likely subject to significant change and improvement, and with a limited coverage of functionality. We are actively developing this codebase.
189190

190191
## Current flows
191192

192-
The ArmBackend has a two stage process,
193-
- Compile to TOSA to rationalise the graph into known hardware support profiles. Currently this is to v0.80 TOSA BI with specific concern to a subset which gives support on Ethos-U55, the target of the initial prototype efforts.
193+
The EthosUBackend has a two stage process,
194+
- Compile to TOSA to rationalise the graph into known hardware support profiles. Currently this is to v0.80 TOSA BI with specific concern to a subset which gives support on Ethos-U55 and Ethos-U85, the target of the initial prototype efforts. This calls into the TOSABackend.
194195
- Lower via the ethos-u-vela compilation flow which takes TOSA v0.80 as an input and produces a low level commandstream for the hardware which is then passed via the delegate to the ethos-u-core-driver for direct execution.
195196

196-
The ArmPartitioner is currenly used to ensure the operations converted are Ethos-U compatible, but will be extended to offer spec-correct TOSA Base inference and TOSA Main Inference generation in future.
197+
The EthosUPartitioner is currenly used to ensure the operations converted are Ethos-U compatible, but will be extended to offer spec-correct TOSA Base inference and TOSA Main Inference generation in future.
198+
199+
There is also a generic TOSABackend with accompanying TOSAPartitioner and TOSAQuantizer, which are used by the EthosUBackend and friends. The Arm TOSA Backend can be used by it's own to verify the lowering to the TOSA representation of the model (refer to the unit tests in backends/arm/test which uses the TOSA backend in the test suites).
197200

198201
### Controlling compilation
199202

200203
It is possible to control the compilation flow to aid in development and debug of both networks and the code itself.
201204

202-
Configuration of the ArmBackend export flow is controlled by CompileSpec information (essentially used as compilation flags) to determine which of these outputs is produced. In particular this allows for use of the tosa_reference_model to run intermediate output to check for correctness and quantization accuracy without a full loop via hardware implemntation.
203-
204-
As this is in active development see the ArmBackend for accurate information on [compilation flags](https://github.com/pytorch/executorch/blob/29f6dc9353e90951ed3fae3c57ae416de0520067/backends/arm/arm_backend.py#L319-L324)
205+
Configuration of the EthosUBackend export flow is controlled by CompileSpec information (essentially used as compilation flags) to determine which of these outputs is produced. In particular this allows for use of the tosa_reference_model to run intermediate output to check for correctness and quantization accuracy without a full loop via hardware implemntation.
205206

206-
You can also refer to the [example TOSA end-to-end code](/examples/arm/arm_tosa_e2e.py)
207+
As this is in active development see the EthosUBackend for accurate information on [compilation flags](https://github.com/pytorch/executorch/blob/29f6dc9353e90951ed3fae3c57ae416de0520067/backends/arm/arm_backend.py#L319-L324)

backends/arm/_passes/arm_pass_manager.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
2-
# Copyright 2024-2025 Arm Limited and/or its affiliates.
32
# All rights reserved.
3+
# Copyright 2024-2025 Arm Limited and/or its affiliates.
44
#
55
# This source code is licensed under the BSD-style license found in the
66
# LICENSE file in the root directory of this source tree.
@@ -18,6 +18,9 @@
1818
from executorch.backends.arm._passes.convert_expand_copy_to_repeat import (
1919
ConvertExpandCopyToRepeatPass,
2020
)
21+
from executorch.backends.arm._passes.convert_full_like_to_full_pass import (
22+
ConvertFullLikeToFullPass,
23+
)
2124
from executorch.backends.arm._passes.convert_split_to_slice import (
2225
ConvertSplitToSlicePass,
2326
)
@@ -95,6 +98,7 @@ def _tosa_080_BI_pipeline(self, exported_program: ExportedProgram) -> GraphModul
9598
self.add_pass(ConvertMmToBmmPass())
9699
self.add_pass(DecomposeLinearPass())
97100
self.add_pass(ConvertMeanDimToAveragePoolPass())
101+
self.add_pass(ConvertFullLikeToFullPass())
98102

99103
self.add_pass(AnnotateDecomposedMatmulPass())
100104
self.add_pass(QuantizeOperatorArguments())
@@ -133,7 +137,7 @@ def _tosa_080_MI_pipeline(self, exported_program: ExportedProgram) -> GraphModul
133137
self.add_pass(ConvertMeanDimToAveragePoolPass())
134138
self.add_pass(DecomposeDivPass())
135139
self.add_pass(DecomposeSoftmaxesPass())
136-
140+
self.add_pass(ConvertFullLikeToFullPass())
137141
self.add_pass(AnnotateDecomposedMatmulPass())
138142
self.add_pass(QuantizeOperatorArguments())
139143
self.add_pass(FoldAndAnnotateQParamsPass()) # type: ignore[call-arg]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
from executorch.exir.dialects._ops import ops as exir_ops
7+
from executorch.exir.pass_base import ExportPass
8+
9+
10+
class ConvertFullLikeToFullPass(ExportPass):
11+
"""As per the full_like pytorch documentation,
12+
`torch.full_like(input, fill_value)` is equivalent to
13+
`torch.full(input.size(),
14+
fill_value,
15+
dtype=input.dtype,
16+
layout=input.layout,
17+
device=input.device
18+
)`
19+
Skip layout and device since it's not relevant for our backend.
20+
"""
21+
22+
def call_operator(self, op, args, kwargs, meta):
23+
if op not in [
24+
exir_ops.edge.aten.full_like.default,
25+
]:
26+
return super().call_operator(op, args, kwargs, meta)
27+
28+
tensor = args[0].data
29+
full_args = (list(tensor.shape), args[1])
30+
full_kwargs = {"dtype": tensor.dtype}
31+
return super().call_operator(
32+
exir_ops.edge.aten.full.default, full_args, full_kwargs, meta
33+
)

0 commit comments

Comments
 (0)