2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef __LUCI_QUANTIZATION_UTILS_H__
18 #define __LUCI_QUANTIZATION_UTILS_H__
20 #include <luci/IR/CircleNodes.h>
21 #include <loco/IR/TensorShape.h>
26 // Compute scale using given min/max for symmetric quantization (int8/int16)
27 void compute_sym_scale(float min, float max, float &scaling_factor, float &nudged_min,
28 float &nudged_max, loco::DataType out_type = loco::DataType::S16);
30 // Compute scale/zp using given min/max for asymmetric quantization (uint8)
31 void compute_asym_scale_zp(float min, float max, float &scaling_factor, int64_t &zp,
32 float &nudged_min, float &nudged_max);
34 // Asymmetric per-layer quantization of weights (const tensor) using given min/max values
35 // NOTE: in-place update of node data
36 void asymmetric_wquant_with_minmax_per_layer(CircleConst *node, float min, float max,
37 float &scaling_factor, int64_t &zp, float &nudged_min,
40 // Symmetric per-layer quantization of weights (const tensor) using given min/max values
41 // NOTE: in-place update of node data
42 void symmetric_wquant_with_minmax_per_layer(CircleConst *node, float min, float max,
43 float &scaling_factor, float &nudged_min,
46 // Helper function to get channel dimension
47 // TODO Embed this function into iterate_per_channel
48 bool get_channel_dim_index(CircleConst *node, loco::TensorShape &dimension,
49 int32_t &channel_dim_index);
51 // Calculate offset of the given indices in dimension
52 uint32_t cal_offset(loco::TensorShape &dimension, uint32_t *indices);
54 // Backward propagation of concatenation qparam
55 void propagate_concat_quantparam(luci::CircleConcatenation *concat);
57 // Backward propagation of pad_v2 qparam
58 void propagate_pad_v2_quantparam(luci::CirclePadV2 *pad_v2);
60 // Return true if the node is quantized
61 bool is_quantized(const CircleNode *node);
63 // Return true if the node is fp32
64 bool is_fp32(const CircleNode *node);
68 MinMax, // Quantize using recorded min/max
69 PreDefinedLogistic, // Quantize using pre-defined values
70 PreDefinedTanh, // Quantize using pre-defined values
71 PreDefinedSoftmax, // Quantize using pre-defined values
72 IntScale, // Round scale to a positive integer
75 ActivationQType activation_qtype(const CircleNode *node);
77 // Create qparam with pre-defined values for speical operators
78 std::unique_ptr<CircleQuantParam> make_predefined_qparam(CircleNode *node, loco::DataType dtype);
79 std::unique_ptr<CircleQuantParam> make_predefined_qparam(ActivationQType qtype,
80 loco::DataType dtype);
82 // Update node's scale to a positive integer (for special Ops e.g., Floor, Ceil)
83 void set_int_scale(luci::CircleNode *node);
85 // Quantize const tensor using its min/max values
86 void quant_const(luci::CircleConst *node, loco::DataType quant_type);
88 // Check that a node is quantized without significant loss of precision;
89 // Emits warnings to log with WARN
90 void warn_accuracy_with_range(luci::CircleNode *n);
94 #endif // __LUCI_QUANTIZATION_UTILS_H__