Skip to content
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

[Relay][Quantization] Extend FakeQuantizationToInteger to more ops #8241

Merged
merged 6 commits into from
Aug 3, 2021
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
146 changes: 146 additions & 0 deletions include/tvm/ir/affine_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* 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.
*/

/*!
* \file tvm/ir/affine_type.h
* \brief Quantized Tensor Types.
*/
#ifndef TVM_IR_AFFINE_TYPE_H_
#define TVM_IR_AFFINE_TYPE_H_

#include <tvm/ir/expr.h>
#include <tvm/ir/type.h>

namespace tvm {

/*!
* \brief AffineType representation
* \sa AffineType
*/
class AffineTypeNode : public Object {
public:
/*!
* \brief Span that points to the original source code.
* Reserved debug information.
*/
mutable Span span;

static constexpr const char* _type_key = "AffineType";
static constexpr const bool _type_has_method_sequal_reduce = true;
static constexpr const bool _type_has_method_shash_reduce = true;
TVM_DECLARE_BASE_OBJECT_INFO(AffineTypeNode, Object);
};

/*!
* \brief Managed reference to AffineTypeNode.
* \sa AffineTypeNode
*/
class AffineType : public ObjectRef {
public:
TVM_DEFINE_OBJECT_REF_METHODS(AffineType, ObjectRef, AffineTypeNode);
};

/*!
* \brief TensorAffineType representation
* \sa TensorAffineType
*
* This Type represents a quantized integer tensor that can be converted
* back to real space via the x_real = scale * (x_quant - zero_point)
*/
class TensorAffineTypeNode : public AffineTypeNode {
public:
/*! \brief The scale of this type */
RelayExpr scale;
/*! \brief The zero point of this type */
RelayExpr zero_point;
/*! \brief The data type of this type */
DataType dtype;

void VisitAttrs(tvm::AttrVisitor* v) {
v->Visit("scale", &scale);
v->Visit("zero_point", &zero_point);
v->Visit("dtype", &dtype);
}

bool SEqualReduce(const TensorAffineTypeNode* other, SEqualReducer equal) const {
equal->MarkGraphNode();
return equal(scale, other->scale) && equal(zero_point, other->zero_point) &&
equal(dtype, other->dtype);
}

void SHashReduce(SHashReducer hash_reduce) const {
hash_reduce->MarkGraphNode();
hash_reduce(scale);
hash_reduce(zero_point);
hash_reduce(dtype);
}

static constexpr const char* _type_key = "TensorAffineType";
TVM_DECLARE_BASE_OBJECT_INFO(TensorAffineTypeNode, AffineTypeNode);
};

/*!
* \brief Managed reference to AffineTypes.
* \sa AffineTypeNode
*/
class TensorAffineType : public AffineType {
public:
TVM_DLL TensorAffineType(RelayExpr scale, RelayExpr zero_point, DataType dtype);

TVM_DEFINE_OBJECT_REF_METHODS(TensorAffineType, AffineType, TensorAffineTypeNode);
};

/*!
* \brief TupleAffineType representation
* \sa TupleAffineType
*/
class TupleAffineTypeNode : public AffineTypeNode {
public:
/*! \brief The types of this tuple*/
Array<TensorAffineType> types;

void VisitAttrs(tvm::AttrVisitor* v) { v->Visit("types", &types); }

bool SEqualReduce(const TupleAffineTypeNode* other, SEqualReducer equal) const {
equal->MarkGraphNode();
return equal(types, other->types);
}

void SHashReduce(SHashReducer hash_reduce) const {
hash_reduce->MarkGraphNode();
hash_reduce(types);
}

static constexpr const char* _type_key = "TupleAffineType";
TVM_DECLARE_BASE_OBJECT_INFO(TupleAffineTypeNode, AffineTypeNode);
};

/*!
* \brief Managed reference to TupleAffineTypes.
* \sa TupleAffineType
*/
class TupleAffineType : public AffineType {
public:
TVM_DLL TupleAffineType(Array<TensorAffineType> types);

TVM_DEFINE_OBJECT_REF_METHODS(TupleAffineType, AffineType, TupleAffineTypeNode);
};

} // namespace tvm
#endif // TVM_IR_AFFINE_TYPE_H_
1 change: 1 addition & 0 deletions python/tvm/ir/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from .type import Type, TypeKind, PrimType, PointerType, TypeVar, GlobalTypeVar, TupleType
from .type import TypeConstraint, FuncType, IncompleteType, RelayRefType
from .tensor_type import TensorType
from .affine_type import TensorAffineType, TupleAffineType
from .type_relation import TypeCall, TypeRelation
from .expr import BaseExpr, PrimExpr, RelayExpr, GlobalVar, Range
from .op import Op, register_op_attr, register_intrin_lowering
Expand Down
69 changes: 69 additions & 0 deletions python/tvm/ir/affine_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 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.
"""Types for quantized Tensors."""
import tvm._ffi

from .base import Node
from . import _ffi_api


class AffineType(Node):
"""The base class of Affine Types."""

def __eq__(self, other):
"""Compare two types for structural equivalence."""
return bool(tvm.ir.structural_equal(self, other))

def __ne__(self, other):
return not self.__eq__(other)


@tvm._ffi.register_object("TensorAffineType")
class TensorAffineType(AffineType):
"""The quantized type of a tensor, with scale, zero point, and datatype

The real space value is calculated as x = x_q * scale + zero_point

Parameters
----------
scale: Expr
The scale

zero_point: Expr
The zero_point

dtype : str
The content data type.
"""

def __init__(self, scale, zero_point, dtype):
self.__init_handle_by_constructor__(_ffi_api.TensorAffineType, scale, zero_point, dtype)


@tvm._ffi.register_object("TupleAffineType")
class TupleAffineType(AffineType):
"""Affine types of a node with multiple outputs

Parameters
----------
types : List[TensorAffineType]
The shape of the Tensor

"""

def __init__(self, types):
self.__init_handle_by_constructor__(_ffi_api.TupleAffineType, types)
2 changes: 1 addition & 1 deletion python/tvm/relay/frontend/onnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ def _impl_v11(cls, inputs, attr, params):
if len(inputs) == 3:
value = fold_constant(_op.take(inputs[2], _op.const(0)))
else:
value = 0
value = 0.0

pad_width_expr = fold_constant(_op.transpose(_op.reshape(pads, (2, -1))))
pad_mode = attr.get("mode", b"constant").decode("utf-8")
Expand Down
Loading