| 1108 | } |
| 1109 | |
| 1110 | void Calibration::_insertScale() { |
| 1111 | for (const auto iter : _scales) { |
| 1112 | std::unique_ptr<MNN::TensorDescribeT> describe(new MNN::TensorDescribeT); |
| 1113 | auto des = iter.first.lock(); |
| 1114 | if (!des) { |
| 1115 | continue; |
| 1116 | } |
| 1117 | if (des->index < 0) { |
| 1118 | continue; |
| 1119 | } |
| 1120 | |
| 1121 | describe->index = des->index; |
| 1122 | describe->quantInfo.reset(new MNN::TensorQuantInfoT); |
| 1123 | describe->quantInfo->scale = iter.second.first; |
| 1124 | describe->quantInfo->zero = iter.second.second; |
| 1125 | describe->quantInfo->type = MNN::DataType_DT_INT8; |
| 1126 | describe->quantInfo->min = -1 * _featureClampValue; |
| 1127 | describe->quantInfo->max = 1 * _featureClampValue; |
| 1128 | auto dstiter = _tensorDescribes.find(des->index); |
| 1129 | if (dstiter == _tensorDescribes.end()) { |
| 1130 | _tensorDescribes.insert(std::make_pair(des->index, std::move(describe))); |
| 1131 | } else { |
| 1132 | dstiter->second->quantInfo = std::move(describe->quantInfo); |
| 1133 | } |
| 1134 | } |
| 1135 | for (auto& op : _originalModel->oplists) { |
| 1136 | const auto opType = op->type; |
| 1137 | |
| 1138 | std::vector<std::string>::iterator iter = std::find(_skip_quant_ops.begin(), _skip_quant_ops.end(), op->name); |
| 1139 | if (iter != _skip_quant_ops.end()) { |
| 1140 | continue; |
| 1141 | } |
| 1142 | |
| 1143 | if (opType != MNN::OpType_Convolution && opType != MNN::OpType_ConvolutionDepthwise && opType != MNN::OpType_Deconvolution) { |
| 1144 | continue; |
| 1145 | } |
| 1146 | if (op->inputIndexes.size() > 1) { |
| 1147 | continue; |
| 1148 | } |
| 1149 | if (_tensorMap[op->inputIndexes[0]].first.lock() == nullptr || _tensorMap[op->outputIndexes[0]].first.lock() == nullptr) { |
| 1150 | continue; |
| 1151 | } |
| 1152 | auto inputTensor = _tensorMap[op->inputIndexes[0]].second; |
| 1153 | auto outputTensor = _tensorMap[op->outputIndexes[0]].second; |
| 1154 | if (inputTensor == nullptr || outputTensor == nullptr) { |
| 1155 | continue; |
| 1156 | } |
| 1157 | // below is Conv/DepthwiseConv weight quant |
| 1158 | auto weakPtr0 = std::weak_ptr<Tensor::InsideDescribe::NativeInsideDescribe>(TensorUtils::getDescribeOrigin(inputTensor)->mContent); |
| 1159 | auto weakPtr1 = std::weak_ptr<Tensor::InsideDescribe::NativeInsideDescribe>(TensorUtils::getDescribeOrigin(outputTensor)->mContent); |
| 1160 | const float inputScale = _scales[weakPtr0].first; |
| 1161 | const float outputScale = _scales[weakPtr1].first; |
| 1162 | const int inputChannel = inputTensor->channel(); |
| 1163 | const int outputChannel = outputTensor->channel(); |
| 1164 | auto param = op->main.AsConvolution2D(); |
| 1165 | param->common->inputCount = inputChannel; |
| 1166 | const int channles = param->common->outputCount; |
| 1167 | param->symmetricQuan.reset(new MNN::QuantizedFloatParamT); |
nothing calls this directly
no test coverage detected