Skip to content

Qualcomm AI Engine Direct - support dim_order #7189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion backends/qualcomm/_passes/remove_redundancy.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class RemoveRedundancy(ExportPass):
"""
Trim the 'identity' operators to reduce the unnecessary copy overhead.
Trim certain operators to reduce unnecessary overhead.
"""

redundant_ops = {
Expand All @@ -21,6 +21,10 @@ class RemoveRedundancy(ExportPass):
torch.ops.aten.alias.default,
exir_ops.edge.aten.alias.default,
exir_ops.edge.aten.lift_fresh_copy.default,
# remove this target if '_skip_dim_order' is set to False
exir_ops.edge.dim_order_ops._to_dim_order_copy.default,
# remove channel_last / contiguous _to_copy if '_skip_dim_order' is set to True
exir_ops.edge.aten._to_copy.default,
}

def __init__(self):
Expand All @@ -31,6 +35,13 @@ def _remove(self, graph_module: torch.fx.GraphModule) -> torch.fx.GraphModule:
if n.target not in self.redundant_ops:
continue

# do not remove cast operator
if (
n.target == exir_ops.edge.aten._to_copy.default
and "memory_format" not in n.kwargs
):
continue

to_be_remove = n
for user_n in list(n.users.keys()):
user_n.replace_input_with(n, n.args[0])
Expand Down
4 changes: 3 additions & 1 deletion backends/qualcomm/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def forward(self, x):


class Conv2dSequential(torch.nn.Module):
def __init__(self, bias=True):
def __init__(self, bias=True, channel_last=False):
super().__init__()
self.first = torch.nn.Conv2d(
in_channels=1,
Expand All @@ -341,8 +341,10 @@ def __init__(self, bias=True):
padding=1,
bias=bias,
)
self.channel_last = channel_last

def forward(self, x):
x = x.to(memory_format=torch.channels_last) if self.channel_last else x
return self.second(self.first(x))


Expand Down
21 changes: 21 additions & 0 deletions backends/qualcomm/tests/test_qnn_delegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ def test_qnn_backend_conv2d(self):
with self.subTest(i=i):
self.lower_module_and_test_output(module, sample_input)

def test_qnn_backend_conv2d_channel_last(self):
modules = [
Conv2dSequential(channel_last=True), # noqa: F405
Conv2dSequential(bias=False, channel_last=True), # noqa: F405
]
sample_input = (torch.randn([1, 1, 3, 3]),)
for i, module in enumerate(modules):
with self.subTest(i=i):
self.lower_module_and_test_output(module, sample_input)

def test_qnn_backend_conv_transpose2d(self):
modules = [
ConvTranspose2dSingle(), # noqa: F405
Expand Down Expand Up @@ -814,6 +824,17 @@ def test_qnn_backend_conv2d(self):
module = self.get_qdq_module(module, sample_input)
self.lower_module_and_test_output(module, sample_input)

def test_qnn_backend_conv2d_channel_last(self):
modules = [
Conv2dSequential(channel_last=True), # noqa: F405
Conv2dSequential(bias=False, channel_last=True), # noqa: F405
]
sample_input = (torch.randn([1, 1, 3, 3]),)
for i, module in enumerate(modules):
with self.subTest(i=i):
module = self.get_qdq_module(module, sample_input)
self.lower_module_and_test_output(module, sample_input)

def test_qnn_backend_conv_transpose2d(self):
modules = [
ConvTranspose2dSingle(), # noqa: F405
Expand Down
1 change: 0 additions & 1 deletion backends/qualcomm/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ def qnn_capture_config():
def qnn_edge_config() -> exir.EdgeCompileConfig:
return exir.EdgeCompileConfig(
_check_ir_validity=False,
_skip_dim_order=True, # TODO(T182928844): Delegate dim order op to backend.
)


Expand Down
Loading