blob: 7c2acbcb06d45e2c2979f77eae91579032fb5b2c [file]
/*
* 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/relay/quantize.h
* \brief Header of definitions for quantization
*/
#ifndef TVM_RELAY_QUANTIZE_QUANTIZE_H_
#define TVM_RELAY_QUANTIZE_QUANTIZE_H_
#include <tvm/relay/expr.h>
#include <tvm/relay/op.h>
#include <string>
#include "../transforms/pattern_utils.h"
namespace tvm {
namespace relay {
namespace quantize {
/*! \brief Kind of annotate field */
enum QAnnotateKind : int { kQIdentity = 0, kQInput = 1, kQWeight = 2, kQActivation = 3 };
/*! \brief Attribute for simulated quantize operator */
struct SimulatedQuantizeAttrs : public tvm::AttrsNode<SimulatedQuantizeAttrs> {
int kind;
bool sign;
std::string rounding;
TVM_DECLARE_ATTRS(SimulatedQuantizeAttrs, "relay.attrs.SimulatedQuantizeAttrs") {
TVM_ATTR_FIELD(kind).describe("kind of field, hint for nbit/dtype configuration.");
TVM_ATTR_FIELD(sign).set_default(true).describe("whether to use signed data type.");
TVM_ATTR_FIELD(rounding).set_default("round").describe(
"rounding mode. Can be 'floor', 'ceil', 'round'");
}
};
class QConfig;
/*!
* \brief Container for build configuration options
*/
class QConfigNode : public Object {
public:
int nbit_input = 8;
int nbit_weight = 8;
int nbit_activation = 32;
DataType dtype_input = DataType::Int(8);
DataType dtype_weight = DataType::Int(8);
DataType dtype_activation = DataType::Int(32);
std::string calibrate_mode = "global_scale";
double global_scale = 8.0;
std::string weight_scale = "power2";
bool skip_dense_layer = true;
Array<Expr> skip_conv_layers = Array<Expr>(ObjectPtr<Object>(nullptr));
bool do_simulation = false;
bool round_for_shift = true;
Array<Expr> debug_enabled_ops = Array<Expr>(ObjectPtr<Object>(nullptr));
std::string rounding = "UPWARD";
int calibrate_chunk_by = -1;
std::string partition_conversions = "disabled";
void VisitAttrs(AttrVisitor* v) {
v->Visit("nbit_input", &nbit_input);
v->Visit("nbit_weight", &nbit_weight);
v->Visit("nbit_activation", &nbit_activation);
v->Visit("dtype_input", &dtype_input);
v->Visit("dtype_weight", &dtype_weight);
v->Visit("dtype_activation", &dtype_activation);
v->Visit("calibrate_mode", &calibrate_mode);
v->Visit("global_scale", &global_scale);
v->Visit("weight_scale", &weight_scale);
v->Visit("skip_dense_layer", &skip_dense_layer);
v->Visit("skip_conv_layers", &skip_conv_layers);
v->Visit("do_simulation", &do_simulation);
v->Visit("round_for_shift", &round_for_shift);
v->Visit("debug_enabled_ops", &debug_enabled_ops);
v->Visit("rounding", &rounding);
v->Visit("calibrate_chunk_by", &calibrate_chunk_by);
v->Visit("partition_conversions", &partition_conversions);
}
static constexpr const char* _type_key = "relay.quantize.QConfig";
TVM_DECLARE_FINAL_OBJECT_INFO(QConfigNode, Object);
};
/*!
* \brief Container for build configuration options
*/
class QConfig : public ObjectRef {
public:
QConfig() {}
explicit QConfig(ObjectPtr<Object> n) : ObjectRef(n) {}
const QConfigNode* operator->() const { return static_cast<const QConfigNode*>(get()); }
QConfigNode* operator->() { return static_cast<QConfigNode*>(get_mutable()); }
/*!
* \brief Push a new BuildConfig context onto the thread local stack.
* \param build_config The configuration to set as the current context.
*/
static void EnterQConfigScope(const QConfig& qconfig);
/*!
* \brief Pop a build config off the thread local context stack, restoring the previous
* configuration as the current context.
*/
static void ExitQConfigScope();
/*!
* \brief Get the current BuildConfig context from thread local storage, or a default
* configuration if a BuildConfig scope has not been entered.
* \return The configuration that is the current context.
*/
static QConfig& Current();
using ContainerType = QConfigNode;
};
/*!
* \brief RAII container to provide a scoped BuildConfig context. Pushes a configuration onto the
* context stack when constructed, and pops it when destructed.
*/
struct QConfigContext {
/*!
* \brief Enter a new BuildConfig context. The given BuildConfig becomes the new current
* context. When the BuildConfigContext is destructed, the previous context is restored.
* \param build_config The BuildConfig to set as the new current context.
*/
explicit QConfigContext(const QConfig& qconfig) { QConfig::EnterQConfigScope(qconfig); }
/*! \brief Destructor. Pops the context off the thread local stack. */
~QConfigContext() { QConfig::ExitQConfigScope(); }
};
} // namespace quantize
} // namespace relay
} // namespace tvm
#endif // TVM_RELAY_QUANTIZE_QUANTIZE_H_