Skip to content

Commit 4789975

Browse files
committed
Qualcomm AI Engine Direct - GA DIT
Summary: - Add DIT example script - Use HistogramObserver as act_observer to resolve accuracy issue - Add the test for DIT - Support UpsampleBicubic - Remove unused pass convert_upsample_bicubic2d.py
1 parent 95a1db5 commit 4789975

File tree

17 files changed

+356
-56
lines changed

17 files changed

+356
-56
lines changed

backends/qualcomm/_passes/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from .convert_bmm_to_matmul import ConvertBmmToMatmul
1212
from .convert_conv1d_to_conv2d import ConvertConv1dToConv2d
1313
from .convert_square_to_pow import ConvertSquareToPow
14-
from .convert_upsample_bicubic2d import ConvertUpsampleBicubicWithBilinear
1514
from .decompose_any import DecomposeAny
1615
from .decompose_cdist import DecomposeCDist
1716
from .decompose_einsum import DecomposeEinsum
@@ -48,7 +47,6 @@
4847
ConvertBmmToMatmul,
4948
ConvertConv1dToConv2d,
5049
ConvertSquareToPow,
51-
ConvertUpsampleBicubicWithBilinear,
5250
DecomposeAny,
5351
DecomposeCDist,
5452
DecomposeEinsum,

backends/qualcomm/_passes/convert_upsample_bicubic2d.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

backends/qualcomm/_passes/layout_transform.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class LayoutTransform(ExportPass):
3838
exir_ops.edge.aten.native_group_norm.default,
3939
exir_ops.edge.aten.pixel_shuffle.default,
4040
exir_ops.edge.aten.pixel_unshuffle.default,
41+
exir_ops.edge.aten.upsample_bicubic2d.default,
42+
exir_ops.edge.aten.upsample_bicubic2d.vec,
4143
exir_ops.edge.aten.upsample_bilinear2d.default,
4244
exir_ops.edge.aten.upsample_bilinear2d.vec,
4345
exir_ops.edge.aten.upsample_nearest2d.default,

backends/qualcomm/_passes/qnn_pass_manager.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
ConvertBmmToMatmul,
1717
ConvertConv1dToConv2d,
1818
ConvertSquareToPow,
19-
ConvertUpsampleBicubicWithBilinear,
2019
DecomposeAny,
2120
DecomposeCDist,
2221
DecomposeEinsum,
@@ -82,7 +81,6 @@ def get_capture_program_passes():
8281
(AnnotateUnbind, True),
8382
(ConvertBmmToMatmul, True),
8483
(ConvertConv1dToConv2d, True),
85-
(ConvertUpsampleBicubicWithBilinear, False),
8684
(DecomposeAny, True),
8785
(ExpandBroadcastTensorShape, False),
8886
(FixedLinearKeepDim, True),

backends/qualcomm/_passes/utils.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ def get_passes_dependency_for_capture_program():
6666
AnnotateUnbind,
6767
ConvertBmmToMatmul,
6868
ConvertConv1dToConv2d,
69-
ConvertUpsampleBicubicWithBilinear,
7069
DecomposeAny,
7170
DecomposeLinalgVectorNorm,
7271
ExpandBroadcastTensorShape,
@@ -86,19 +85,17 @@ def get_passes_dependency_for_capture_program():
8685
AnnotateQuantAttrs: [
8786
RecomposePixelUnshuffle,
8887
ConvertBmmToMatmul,
89-
ConvertUpsampleBicubicWithBilinear,
9088
RemoveRedundancy,
9189
],
9290
AnnotateStack: [RemoveRedundancy],
9391
AnnotateUnbind: [RemoveRedundancy],
9492
ConvertBmmToMatmul: [RecomposePixelUnshuffle],
95-
ConvertUpsampleBicubicWithBilinear: [RemoveRedundancy],
9693
DecomposeAny: [RemoveRedundancy],
9794
DecomposeLinalgVectorNorm: [RemoveRedundancy],
9895
ExpandBroadcastTensorShape: [FoldQDQ],
9996
FixedLinearKeepDim: [FoldQDQ],
10097
FoldQDQ: [AnnotateQuantAttrs, AnnotateStack, AnnotateUnbind],
101-
I64toI32: [ConvertUpsampleBicubicWithBilinear, RemoveRedundancy],
98+
I64toI32: [RemoveRedundancy],
10299
LayoutTransform: [
103100
AnnotateQuantAttrs,
104101
ConvertConv1dToConv2d,

backends/qualcomm/builders/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
op_relu,
6767
op_repeat,
6868
op_reshape,
69+
op_resize,
6970
op_rms_norm,
7071
op_rsqrt,
7172
op_scalar_tensor,
@@ -155,6 +156,7 @@
155156
op_relu,
156157
op_repeat,
157158
op_reshape,
159+
op_resize,
158160
op_rms_norm,
159161
op_rsqrt,
160162
op_scalar_tensor,
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
from typing import cast, Dict
7+
8+
import executorch.backends.qualcomm.python.PyQnnWrapperAdaptor as PyQnnWrapper
9+
import numpy as np
10+
import torch
11+
12+
from executorch.backends.qualcomm.utils.constants import QCOM_DATA
13+
14+
from .node_visitor import NodeVisitor, register_node_visitor
15+
from .qnn_constants import OpResize, QNN_OP_PACKAGE_NAME_QTI_AISW
16+
17+
18+
@register_node_visitor
19+
class Resize(NodeVisitor):
20+
# Because QNN support ResizeBilinear and ResizeNearestNeighbor, only bicubic need to be handled in resize op
21+
target = ["aten.upsample_bicubic2d.vec"]
22+
23+
def __init__(self, *args) -> None:
24+
super().__init__(*args)
25+
26+
def define_node(
27+
self,
28+
node: torch.fx.Node,
29+
nodes_to_wrappers: Dict[torch.fx.Node, PyQnnWrapper.TensorWrapper],
30+
) -> PyQnnWrapper.PyQnnOpWrapper:
31+
input_node = self.get_node(node.args[0])
32+
input_tensor = self.get_tensor(input_node, node)
33+
input_tensor_wrapper = self.define_tensor(
34+
input_node,
35+
node,
36+
input_tensor,
37+
PyQnnWrapper.Qnn_TensorType_t.QNN_TENSOR_TYPE_NATIVE,
38+
nodes_to_wrappers,
39+
)
40+
align_corners = cast(bool, node.args[2])
41+
transformation_mode = np.uint32(2) if align_corners else np.uint32(1)
42+
# This builder supports only bicubic resize.
43+
interpolation_mode = np.uint32(2)
44+
cubic_coeff = np.float32(-0.75)
45+
46+
output_tensor = self.get_tensor(node, node)
47+
output_tensor_wrapper = self.define_tensor(
48+
node,
49+
node,
50+
output_tensor,
51+
PyQnnWrapper.Qnn_TensorType_t.QNN_TENSOR_TYPE_NATIVE,
52+
nodes_to_wrappers,
53+
)
54+
resize_op = PyQnnWrapper.PyQnnOpWrapper(
55+
node.name,
56+
QNN_OP_PACKAGE_NAME_QTI_AISW,
57+
OpResize.op_name,
58+
)
59+
resize_op.AddInputTensors([input_tensor_wrapper])
60+
resize_op.AddOutputTensors([output_tensor_wrapper])
61+
62+
resize_op.AddScalarParam(
63+
OpResize.param_exclude_outside,
64+
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_BOOL_8,
65+
{QCOM_DATA: False},
66+
)
67+
resize_op.AddScalarParam(
68+
OpResize.param_transformation_mode,
69+
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_UINT_32,
70+
{QCOM_DATA: transformation_mode},
71+
)
72+
73+
resize_op.AddScalarParam(
74+
OpResize.param_interpolation_mode,
75+
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_UINT_32,
76+
{QCOM_DATA: interpolation_mode},
77+
)
78+
resize_op.AddScalarParam(
79+
OpResize.param_cubic_coeff,
80+
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_FLOAT_32,
81+
{QCOM_DATA: cubic_coeff},
82+
)
83+
84+
return resize_op

backends/qualcomm/builders/op_upsample_bilinear2d.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,23 @@ def define_node(
4545
nodes_to_wrappers,
4646
)
4747

48-
reisze_bilinear_op = PyQnnWrapper.PyQnnOpWrapper(
48+
resize_bilinear_op = PyQnnWrapper.PyQnnOpWrapper(
4949
node.name,
5050
QNN_OP_PACKAGE_NAME_QTI_AISW,
5151
OpResizeBilinear.op_name,
5252
)
53-
reisze_bilinear_op.AddInputTensors([input_tensor_wrapper])
54-
reisze_bilinear_op.AddOutputTensors([output_tensor_wrapper])
53+
resize_bilinear_op.AddInputTensors([input_tensor_wrapper])
54+
resize_bilinear_op.AddOutputTensors([output_tensor_wrapper])
5555

56-
reisze_bilinear_op.AddScalarParam(
56+
resize_bilinear_op.AddScalarParam(
5757
OpResizeBilinear.param_align_corners,
5858
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_BOOL_8,
5959
{QCOM_DATA: node.args[2]},
6060
)
61-
reisze_bilinear_op.AddScalarParam(
61+
resize_bilinear_op.AddScalarParam(
6262
OpResizeBilinear.param_half_pixel_centers,
6363
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_BOOL_8,
6464
{QCOM_DATA: not node.args[2]},
6565
)
6666

67-
return reisze_bilinear_op
67+
return resize_bilinear_op

backends/qualcomm/builders/op_upsample_nearest2d.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,23 @@ def define_node(
4545
nodes_to_wrappers,
4646
)
4747

48-
reisze_nearest_op = PyQnnWrapper.PyQnnOpWrapper(
48+
resize_nearest_op = PyQnnWrapper.PyQnnOpWrapper(
4949
node.name,
5050
QNN_OP_PACKAGE_NAME_QTI_AISW,
5151
OpResizeNearestNeighbor.op_name,
5252
)
53-
reisze_nearest_op.AddInputTensors([input_tensor_wrapper])
54-
reisze_nearest_op.AddOutputTensors([output_tensor_wrapper])
53+
resize_nearest_op.AddInputTensors([input_tensor_wrapper])
54+
resize_nearest_op.AddOutputTensors([output_tensor_wrapper])
5555
# align_corners is guaranteed to be false
56-
reisze_nearest_op.AddScalarParam(
56+
resize_nearest_op.AddScalarParam(
5757
OpResizeNearestNeighbor.param_align_corners,
5858
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_BOOL_8,
5959
{QCOM_DATA: False},
6060
)
61-
reisze_nearest_op.AddScalarParam(
61+
resize_nearest_op.AddScalarParam(
6262
OpResizeNearestNeighbor.param_half_pixel_centers,
6363
PyQnnWrapper.Qnn_DataType_t.QNN_DATATYPE_BOOL_8,
6464
{QCOM_DATA: True},
6565
)
6666

67-
return reisze_nearest_op
67+
return resize_nearest_op

backends/qualcomm/builders/qnn_constants.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,16 @@ class OpReshape:
408408
op_name: str = "Reshape"
409409

410410

411+
@dataclass(init=False, frozen=True)
412+
class OpResize:
413+
op_name: str = "Resize"
414+
param_exclude_outside: str = "exclude_outside"
415+
param_transformation_mode: str = "transformation_mode"
416+
param_interpolation_mode: str = "interpolation_mode"
417+
param_nearest_mode: str = "nearest_mode"
418+
param_cubic_coeff: str = "cubic_coeff"
419+
420+
411421
@dataclass(init=False, frozen=True)
412422
class OpResizeBilinear:
413423
op_name: str = "ResizeBilinear"

backends/qualcomm/partition/common_defs.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
exir_ops.edge.aten.clone.default,
1414
exir_ops.edge.aten.slice_scatter.default,
1515
exir_ops.edge.aten.copy.default,
16-
exir_ops.edge.aten.upsample_bicubic2d.vec,
1716
exir_ops.edge.quantized_decomposed.embedding_4bit.dtype,
1817
]
1918

backends/qualcomm/quantizer/annotators.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,13 @@ def annotate_upsample_bilinear2d(
536536
annotate_single_in_single_out(node, quantization_config)
537537

538538

539+
@register_annotator([torch.ops.aten.upsample_bicubic2d.vec])
540+
def annotate_upsample_upsample_bicubic2d(
541+
node: Node, quantization_config: QuantizationConfig
542+
) -> None:
543+
annotate_single_in_single_out(node, quantization_config)
544+
545+
539546
@register_annotator([torch.ops.aten.upsample_nearest2d.vec])
540547
def annotate_upsample_nearest2d(
541548
node: Node, quantization_config: QuantizationConfig

backends/qualcomm/tests/models.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,23 @@ def forward(self, x):
13111311
return x6
13121312

13131313

1314+
class ResizeBicubic(torch.nn.Module):
1315+
def __init__(self, size, scale_factor, align_corners):
1316+
super().__init__()
1317+
self.align_corners = align_corners
1318+
self.scale_factor = scale_factor
1319+
self.size = size
1320+
1321+
def forward(self, x):
1322+
return torch.nn.functional.interpolate(
1323+
x,
1324+
size=self.size,
1325+
scale_factor=self.scale_factor,
1326+
mode="bicubic",
1327+
align_corners=self.align_corners,
1328+
)
1329+
1330+
13141331
class ResizeBilinear2D(torch.nn.Module):
13151332
def __init__(self):
13161333
super().__init__()

0 commit comments

Comments
 (0)