| 213 | } |
| 214 | |
| 215 | static void _insertScale(MNN::NetT* _originalModel, std::map<int, std::pair<float, int32_t>> &_scales, |
| 216 | std::map<int, std::unique_ptr<MNN::TensorDescribeT>> &_tensorDescribes, |
| 217 | std::map<int, std::pair<float, int32_t>> tensorDescribesHasScaleIndex, |
| 218 | int featureBit, int weightBit, int blockSize) { |
| 219 | float _featureClampValue = (float)((1 << (featureBit - 1))); |
| 220 | auto type = MNN::DataType_DT_INT8; |
| 221 | if(featureBit == 16){ |
| 222 | type = MNN::DataType_DT_INT16; |
| 223 | } |
| 224 | std::set<OpType> propagateOpTypes = { OpType_Raster, OpType_ReLU, OpType_ReLU6, OpType_Pooling, |
| 225 | OpType_Interp, OpType_CropAndResize, OpType_ROIPooling}; |
| 226 | for (auto& op : _originalModel->oplists) { |
| 227 | const auto opType = op->type; |
| 228 | |
| 229 | if(propagateOpTypes.find(opType) != propagateOpTypes.end()){ |
| 230 | bool needErase = false; |
| 231 | for(int id = 0; id < op->inputIndexes.size() && needErase == false; ++id){ |
| 232 | auto iter = tensorDescribesHasScaleIndex.find(op->inputIndexes[id]); |
| 233 | if(iter != tensorDescribesHasScaleIndex.end()){ |
| 234 | needErase = true; |
| 235 | } |
| 236 | } |
| 237 | for(int id = 0; id < op->outputIndexes.size() && needErase == false; ++id){ |
| 238 | auto iter = tensorDescribesHasScaleIndex.find(op->outputIndexes[id]); |
| 239 | if(iter != tensorDescribesHasScaleIndex.end()){ |
| 240 | needErase = true; |
| 241 | } |
| 242 | } |
| 243 | if(needErase){ |
| 244 | for(int id = 0; id < op->inputIndexes.size(); ++id){ |
| 245 | auto iter = _scales.find(op->inputIndexes[id]); |
| 246 | if(iter != _scales.end()){ |
| 247 | _scales.erase(iter); |
| 248 | } |
| 249 | } |
| 250 | for(int id = 0; id < op->outputIndexes.size(); ++id){ |
| 251 | auto iter = _scales.find(op->outputIndexes[id]); |
| 252 | if(iter != _scales.end()){ |
| 253 | _scales.erase(iter); |
| 254 | } |
| 255 | } |
| 256 | } |
| 257 | } |
| 258 | } |
| 259 | for (const auto iter : _scales) { |
| 260 | std::unique_ptr<MNN::TensorDescribeT> describe(new MNN::TensorDescribeT); |
| 261 | auto index = iter.first; |
| 262 | |
| 263 | describe->index = index; |
| 264 | describe->quantInfo.reset(new MNN::TensorQuantInfoT); |
| 265 | describe->quantInfo->scale = iter.second.first; |
| 266 | describe->quantInfo->zero = iter.second.second; |
| 267 | describe->quantInfo->type = type; |
| 268 | describe->quantInfo->min = -1 * _featureClampValue; |
| 269 | describe->quantInfo->max = _featureClampValue - 1; |
| 270 | auto dstiter = _tensorDescribes.find(index); |
| 271 | if (dstiter == _tensorDescribes.end()) { |
| 272 | _tensorDescribes.insert(std::make_pair(index, std::move(describe))); |