Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
243784d
[QNN] Disable QNN canonicalization pass.
Jun 6, 2022
71c0cb0
added dependence of the qnn::transform::Legalize pass launch on target.
Jun 21, 2022
a442f70
Added new dense topi operator for the pattern qnn.dense+bias+requantize
Jun 23, 2022
06bfeed
Added support of axis attribute for QNN TOPI ops
Jun 29, 2022
777a9be
Fixed TOPI compute implementation for qnn.add
Jul 4, 2022
3aa343e
Fixed issue with non zero padding value for qnn.conv2d
Jul 5, 2022
46d9edf
Fixed Bias.add for qnn.conv2d
Jul 5, 2022
723b7ab
Added support of depthwise qnn.conv2d topi operator
Jul 6, 2022
ce8a765
Added support of 1D quantization params in qnn.dequantize
Jul 7, 2022
823f46a
Added support of qnn.concatenate
Jul 8, 2022
055ea96
Fixed out of range array access
Jul 12, 2022
8efb58f
Added meta_schedule_original_shape attribute in QDenseAttr and
Jul 26, 2022
82e21cb
Added support of qnn.batch_matmul as a standalone op.
Aug 2, 2022
a63a4e4
Added per channel zp in qnn.dense and qnn.conv2d.
Aug 3, 2022
235084f
Fixed corner cases like dense+bias+bias+rq.
Aug 5, 2022
862ea2e
Added unit test.
Aug 5, 2022
c985961
Removed rq_out_dtype and axis attributes declaration in QConv2DAttra and
Aug 9, 2022
92862ff
Changed target x86->Hexagon to disable QNN passes.
Aug 9, 2022
a287205
Fixed issue with QDenseAttrs and QConv2dAttrs.
Aug 10, 2022
72af59c
Fixed build for Cortex-M.
Aug 10, 2022
9fe7401
Removed QDenseAttrs and QConv2dAttrs
Aug 11, 2022
968be2b
Fix tests after rebase
Oct 17, 2022
b7e6e26
Address code review comments.
Oct 17, 2022
c1b6399
[QNN] Add option to disabe QNN passes.
Oct 18, 2022
d5dc496
Revert changes of GetPassPrefix interface.
Oct 18, 2022
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
10 changes: 10 additions & 0 deletions include/tvm/runtime/data_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ class DataType {
* \return the result type.
*/
DataType element_of() const { return with_lanes(1); }
/*!
* \brief Assignment operator.
*/
DataType& operator=(const DataType& rhs) {
if (this == &rhs) {
return *this;
}
data_ = rhs.data_;
return *this;
}
/*!
* \brief Equal comparator.
* \param other The data type to compare against.
Expand Down
33 changes: 18 additions & 15 deletions python/tvm/relay/backend/te_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,25 +281,28 @@ def get_shape(shape):


@tvm._ffi.register_func("relay.backend.lower_call")
def lower_call(call, inputs, target):
def lower_call(call, inputs, target, otype=None):
"""Lower the call expression to op implementation and tensor outputs."""
assert isinstance(call.op, tvm.ir.Op)
op = call.op

# Prepare the call_node->checked_type(). For the call node inputs, we ensure that
# the shape is Int32. Following code ensures the same for the output as well.
# TODO(@icemelon9): Support recursive tuple
ret_type = call.checked_type
if isinstance(ret_type, _ty.TensorType):
ret_type = _ty.TensorType(get_shape(ret_type.shape), ret_type.dtype)
elif isinstance(ret_type, _ty.TupleType):
new_fields = []
for field in ret_type.fields:
if isinstance(field, _ty.TensorType):
new_fields.append(_ty.TensorType(get_shape(field.shape), field.dtype))
else:
new_fields.append(field)
ret_type = _ty.TupleType(new_fields)
if otype is not None:
ret_type = otype
else:
# Prepare the call_node->checked_type(). For the call node inputs, we ensure that
# the shape is Int32. Following code ensures the same for the output as well.
# TODO(@icemelon9): Support recursive tuple
ret_type = call.checked_type
if isinstance(ret_type, _ty.TensorType):
ret_type = _ty.TensorType(get_shape(ret_type.shape), ret_type.dtype)
elif isinstance(ret_type, _ty.TupleType):
new_fields = []
for field in ret_type.fields:
if isinstance(field, _ty.TensorType):
new_fields.append(_ty.TensorType(get_shape(field.shape), field.dtype))
else:
new_fields.append(field)
ret_type = _ty.TupleType(new_fields)

is_dyn = _ty.is_dynamic(call.checked_type)
for arg in call.args:
Expand Down
35 changes: 34 additions & 1 deletion python/tvm/relay/qnn/op/_qnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@

from tvm import topi

from .. import strategy
from ...op.op import register_compute
from ...op.op import register_injective_schedule
from ...op.op import register_pattern, OpPattern
from ...op.op import register_strategy, register_pattern, OpPattern


@register_compute("qnn.simulated_quantize")
Expand Down Expand Up @@ -50,3 +51,35 @@ def simulated_dequantize_compute(attrs, inputs, output_type):

register_injective_schedule("qnn.simulated_dequantize")
register_pattern("qnn.simulated_dequantize", OpPattern.ELEMWISE)

# qnn.quantize
register_strategy("qnn.quantize", strategy.qnn_quantize_strategy)
register_pattern("qnn.quantize", OpPattern.ELEMWISE)

# qnn.dequantize
register_strategy("qnn.dequantize", strategy.qnn_dequantize_strategy)
register_pattern("qnn.dequantize", OpPattern.ELEMWISE)

# qnn.requantize
register_strategy("qnn.requantize", strategy.qnn_requantize_strategy)
register_pattern("qnn.requantize", OpPattern.ELEMWISE)

# qnn.add
register_strategy("qnn.add", strategy.qnn_add_strategy)
register_pattern("qnn.add", OpPattern.BROADCAST)

# qnn.concatenate
register_strategy("qnn.concatenate", strategy.qnn_concatenate_strategy)
register_pattern("qnn.concatenate", OpPattern.INJECTIVE)

# qnn.conv2d
register_strategy("qnn.conv2d", strategy.qnn_conv2d_strategy)
register_pattern("qnn.conv2d", OpPattern.OUT_ELEMWISE_FUSABLE)

# qnn.dense
register_strategy("qnn.dense", strategy.qnn_dense_strategy)
register_pattern("qnn.dense", OpPattern.OUT_ELEMWISE_FUSABLE)

# qnn.batch_matmul
register_strategy("qnn.batch_matmul", strategy.qnn_batch_matmul_strategy)
register_pattern("qnn.batch_matmul", OpPattern.OUT_ELEMWISE_FUSABLE)
7 changes: 0 additions & 7 deletions python/tvm/relay/qnn/op/qnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
from tvm.topi.nn.qnn import SQNN_DTYPE_TO_CODE
from tvm.topi.x86.utils import target_has_sse41

from ... import op as reg
from ...op import OpPattern
from . import _make, _requantize


Expand Down Expand Up @@ -1212,11 +1210,6 @@ def batch_matmul(x, y, x_zero_point, y_zero_point, x_scale, y_scale, out_dtype="
return _make.batch_matmul(x, y, x_zero_point, y_zero_point, x_scale, y_scale, out_dtype)


# register fuse pattern for qnn ops
reg.register_pattern("qnn.quantize", OpPattern.OPAQUE)
reg.register_pattern("qnn.dequantize", OpPattern.OPAQUE)


def leaky_relu(x, alpha, input_scale, input_zero_point, output_scale, output_zero_point):
"""Quantized leaky relu.

Expand Down
23 changes: 23 additions & 0 deletions python/tvm/relay/qnn/strategy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# pylint: disable=wildcard-import
"""QNN op strategies."""
from __future__ import absolute_import as _abs

from .generic import *
from . import hexagon
Loading