Skip to content

Commit 818725f

Browse files
committed
NXP backend: Prohibit fusion of Transpose operators, to avoid introducing unsupported permutations.
1 parent e23040f commit 818725f

File tree

5 files changed

+38
-8
lines changed

5 files changed

+38
-8
lines changed

backends/nxp/backend/ir/converter/builder/model_builder.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,9 @@ def finish(self) -> tflite_model.Model:
481481
self._make_outputs_channels_first()
482482

483483
# Apply optimizations to the internal TFLite model.
484-
optimizer.Optimizer(self, self.conversion_config).optimize(
484+
optimizer.Optimizer(
485+
self, self.conversion_config, self.neutron_target_spec
486+
).optimize(
485487
self.conversion_config.optimization_whitelist,
486488
self.conversion_config.optimization_blacklist,
487489
)

backends/nxp/backend/ir/tflite_optimizer/optimizations/base_optimization.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@
1212
InputTensorToOpsMap,
1313
OutputTensorToOpMap,
1414
)
15+
from executorch.backends.nxp.backend.neutron_target_spec import NeutronTargetSpec
1516

1617

1718
class BaseOptimization(ABC):
1819
_builder: "model_builder.ModelBuilder"
1920

2021
def __init__(
21-
self, builder: "model_builder.ModelBuilder", conversion_config: ConversionConfig
22+
self,
23+
builder: "model_builder.ModelBuilder",
24+
conversion_config: ConversionConfig,
25+
neutron_target_spec: NeutronTargetSpec,
2226
):
2327
self._builder = builder
2428
self._conversion_config = conversion_config
29+
self.neutron_target_spec = neutron_target_spec
2530

2631
def _create_tensor_to_operator_dictionaries(
2732
self,

backends/nxp/backend/ir/tflite_optimizer/optimizations/prune_transpose_operators.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@
2424
TensorIsNotModelOutput,
2525
TensorsHaveData,
2626
)
27+
from executorch.backends.nxp.backend.neutron_operator_support import (
28+
transposition_is_supported_on_neutron,
29+
)
2730

2831

2932
class FuseTransposeOperators(BaseOptimization):
30-
"""Remove some `Transpose` operators in the following pattern.
33+
"""Remove some `Transpose` operators in the following pattern. This is only done if the resulting permutation is
34+
supported on Neutron.
3135
3236
│ 'x'
3337
┌─────▼─────┐
@@ -61,12 +65,27 @@ def __call__(self) -> bool:
6165
) in matcher.match_patterns():
6266
x = tensor_map["x"]
6367
perm1 = tensor_map["perm1"].tmp_buffer.data
68+
combined_perms = []
6469

6570
# Remove the leading transpose.
6671
for second_transpose in following_transposes:
6772
# Combine the permutations for a new permutation of the second `Transpose`.
6873
perm2 = second_transpose.tmp_inputs[1].tmp_buffer.data
69-
combined_perm = np.array(combine_permutations(perm1, perm2), np.int32)
74+
combined_perms.append(
75+
np.array(combine_permutations(perm1, perm2), np.int32)
76+
)
77+
78+
if not all(
79+
transposition_is_supported_on_neutron(
80+
x.shape.vector, list(perm), self.neutron_target_spec
81+
)
82+
for perm in combined_perms
83+
):
84+
continue # Avoid creating an unsupported permutation.
85+
86+
for second_transpose, combined_perm in zip(
87+
following_transposes, combined_perms
88+
):
7089
second_transpose.tmp_inputs[1] = self._builder.create_tensor_for_data(
7190
combined_perm, "perm"
7291
)

backends/nxp/backend/ir/tflite_optimizer/optimizer.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
FuseTransposeOperators,
2222
RemoveIdentityTransposeOperators,
2323
)
24+
from executorch.backends.nxp.backend.neutron_target_spec import NeutronTargetSpec
2425

2526

2627
class Optimization(Enum):
@@ -55,21 +56,22 @@ def __init__(
5556
self,
5657
builder: "model_builder.ModelBuilder", # noqa F821
5758
conversion_config: ConversionConfig,
59+
neutron_target_spec: NeutronTargetSpec,
5860
):
5961
self._builder = builder
6062

6163
self.optimization_map = {
6264
Optimization.FUSE_TRANSPOSE_OPERATORS: FuseTransposeOperators(
63-
builder, conversion_config
65+
builder, conversion_config, neutron_target_spec
6466
),
6567
Optimization.REMOVE_IDENTITY_TRANSPOSE_OPERATORS: RemoveIdentityTransposeOperators(
66-
builder, conversion_config
68+
builder, conversion_config, neutron_target_spec
6769
),
6870
Optimization.PERMUTE_FULLY_CONNECTED_WEIGHTS_AFTER_RESHAPE: PermuteFullyConnectedWeightsAfterReshape(
69-
builder, conversion_config
71+
builder, conversion_config, neutron_target_spec
7072
),
7173
Optimization.MOVE_ACTIVATION_BEFORE_CONCAT: MoveActivationBeforeConcatenation(
72-
builder, conversion_config
74+
builder, conversion_config, neutron_target_spec
7375
),
7476
}
7577

backends/nxp/backend/neutron_converter_manager.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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.
5+
56
import importlib
67
import logging
78
import multiprocessing
@@ -75,6 +76,7 @@ def convert(self, tflite_model: bytes, target: str) -> bytes:
7576
cctx = self.neutron_converter.CompilationContext()
7677
cctx.targetOpts = self.neutron_converter.getNeutronTarget(target)
7778
cctx.compilationOpts.minNumOpsPerGraph = 1
79+
cctx.compilationOpts.excludeGraphPasses = "MergeTranspose"
7880

7981
logger = multiprocessing.log_to_stderr()
8082
logger.setLevel(logging.WARNING)

0 commit comments

Comments
 (0)