Skip to content

Commit 1b7ae0e

Browse files
committed
NXP backend: Add context dependant partitioning for view_copy.
1 parent 1c77077 commit 1b7ae0e

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

backends/nxp/backend/ir/converter/node_converter.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def _is_dequant_node(node: torch.fx.Node) -> bool:
3838
]
3939

4040

41+
def is_not_qdq_node(node: torch.fx.Node) -> bool:
42+
return not (_is_quant_node(node) or _is_dequant_node(node))
43+
44+
4145
class Target(Enum):
4246
IGNORE = "ignore" # No target platform. Any target specific restrictions will be ignored.
4347

backends/nxp/backend/ir/converter/node_converters/ops_converters/view_copy_converter.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from executorch.backends.nxp.backend.ir.converter.conversion.common import OpsList
1515
from executorch.backends.nxp.backend.ir.converter.node_converter import (
1616
CustomDelegationOptions,
17+
is_not_qdq_node,
1718
NodeConverter,
1819
)
1920
from executorch.backends.nxp.backend.ir.converter.node_converters.shared.reshape_transposition import (
@@ -23,6 +24,7 @@
2324
reshape_options,
2425
)
2526
from torch.fx import Node
27+
from torch.fx.passes.infra.partitioner import Partition
2628
from torch.nn import Parameter
2729

2830

@@ -45,6 +47,27 @@ def _is_supported_in_IR(
4547

4648
return True
4749

50+
@classmethod
51+
def supports_partitioning_result(
52+
cls,
53+
node: Node,
54+
partition_list: list[Partition],
55+
custom_delegation_options: CustomDelegationOptions,
56+
):
57+
view_copy_partitions = [
58+
partition for partition in partition_list if node in partition.nodes
59+
]
60+
assert len(view_copy_partitions) == 1
61+
non_q_dq_partition_nodes = list(
62+
filter(is_not_qdq_node, view_copy_partitions[0].nodes)
63+
)
64+
65+
if len(non_q_dq_partition_nodes) == 1:
66+
# The `view_copy` cannot be the only node in a partition.
67+
return False
68+
69+
return True
70+
4871
@staticmethod
4972
def _safe_compute_flat_size(shape: list[int | str]) -> int:
5073
"""Compute the flat size of a tensor with given shape. Strings and negative dimensions are treated as '1'.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright 2025 NXP
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+
import unittest
7+
8+
import numpy as np
9+
import torch
10+
11+
from executorch.backends.nxp.backend.ir.converter.node_converters.ops_converters import (
12+
ViewCopyConverter,
13+
)
14+
from executorch.backends.nxp.tests.executorch_pipeline import to_quantized_edge_program
15+
from executorch.backends.nxp.tests.executors import graph_contains_any_of_ops
16+
from executorch.exir.dialects._ops import ops as exir_ops
17+
18+
19+
class SingleViewCopyModule(torch.nn.Module):
20+
def __init__(self, new_shape: list[int]):
21+
super().__init__()
22+
self.new_shape = new_shape
23+
24+
def forward(self, x):
25+
return torch.reshape(x, self.new_shape)
26+
27+
28+
class TestContextSensitiveDelegation(unittest.TestCase):
29+
__test__ = False # Prevent interfering with PyTest tests.
30+
31+
@classmethod
32+
def setUpClass(cls):
33+
torch.manual_seed(23)
34+
np.random.seed(42)
35+
36+
def test_single_view_copy_partition(self):
37+
input_shape = (2, 10)
38+
module = SingleViewCopyModule([1, 20])
39+
40+
ep = to_quantized_edge_program(module, input_shape).exported_program()
41+
42+
# Make sure the `view_copy` was not delegated.
43+
assert graph_contains_any_of_ops(
44+
ep.graph, [exir_ops.edge.aten.view_copy.default]
45+
)
46+
assert not any("delegate" in n.name for n in ep.graph.nodes)
47+
48+
def test_single_view_copy_partition__forced_delegation(self):
49+
input_shape = (2, 10)
50+
module = SingleViewCopyModule([1, 20])
51+
52+
def _supported_partitioning(*_):
53+
return True
54+
55+
ViewCopyConverter.supports_partitioning_result = _supported_partitioning
56+
57+
with self.assertRaises(RuntimeError) as e:
58+
to_quantized_edge_program(module, input_shape).exported_program()
59+
assert (
60+
str(e.exception)
61+
== "Model converted with neutron-converter does not contain a NeutronGraph node."
62+
)

0 commit comments

Comments
 (0)