Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / compiler / luci / pass / src / QuantizationUtils.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
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
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #ifndef __LUCI_QUANTIZATION_UTILS_H__
18 #define __LUCI_QUANTIZATION_UTILS_H__
19
20 #include <luci/IR/CircleNodes.h>
21 #include <loco/IR/TensorShape.h>
22
23 namespace luci
24 {
25
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);
29
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);
33
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,
38                                              float &nudged_max);
39
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,
44                                             float &nudged_max);
45
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);
50
51 // Calculate offset of the given indices in dimension
52 uint32_t cal_offset(loco::TensorShape &dimension, uint32_t *indices);
53
54 // Backward propagation of concatenation qparam
55 void propagate_concat_quantparam(luci::CircleConcatenation *concat);
56
57 // Backward propagation of pad_v2 qparam
58 void propagate_pad_v2_quantparam(luci::CirclePadV2 *pad_v2);
59
60 // Return true if the node is quantized
61 bool is_quantized(const CircleNode *node);
62
63 // Return true if the node is fp32
64 bool is_fp32(const CircleNode *node);
65
66 enum ActivationQType
67 {
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
73 };
74
75 ActivationQType activation_qtype(const CircleNode *node);
76
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);
81
82 // Update node's scale to a positive integer (for special Ops e.g., Floor, Ceil)
83 void set_int_scale(luci::CircleNode *node);
84
85 // Quantize const tensor using its min/max values
86 void quant_const(luci::CircleConst *node, loco::DataType quant_type);
87
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);
91
92 } // namespace luci
93
94 #endif // __LUCI_QUANTIZATION_UTILS_H__