| 15 | using namespace MNN::Express; |
| 16 | |
| 17 | void FullQuantAndCoding(std::unique_ptr<MNN::NetT>& netT, std::unique_ptr<MNN::OpT>& op, Compression::Pipeline& proto, SubGraphProtoT* subgraph) { |
| 18 | std::string outputTensorName = subgraph ? subgraph->tensors[op->outputIndexes[0]] : netT->tensorName[op->outputIndexes[0]];; |
| 19 | auto opType = op->type; |
| 20 | if (opType != MNN::OpType_Convolution && opType != MNN::OpType_ConvolutionDepthwise) { |
| 21 | return; |
| 22 | } |
| 23 | if (op->inputIndexes.size() != 1) { |
| 24 | return; |
| 25 | } |
| 26 | |
| 27 | auto findQuantParameters = [&](Compression::Pipeline& proto, std::string outputTensorName) { |
| 28 | for (const auto& algo : proto.algo()) { |
| 29 | if (algo.type() == Compression::CompressionAlgo::QUANTIZE) { |
| 30 | auto quantParams = algo.quant_params(); |
| 31 | for (const auto& layerProto : quantParams.layer()) { |
| 32 | if (layerProto.output_size() <= 0) { |
| 33 | continue; |
| 34 | } |
| 35 | const std::string& outputName = layerProto.output(0).name(); |
| 36 | if ((outputName == outputTensorName) || (outputTensorName == outputName+"__matmul_converted")) { |
| 37 | return layerProto; |
| 38 | } |
| 39 | } |
| 40 | } |
| 41 | } |
| 42 | MNN::Compression::LayerQuantizeParams empty; |
| 43 | return empty; |
| 44 | }; |
| 45 | |
| 46 | auto inputIndex = op->inputIndexes[0]; |
| 47 | int outputIndex = op->outputIndexes[0]; |
| 48 | auto quantParams = findQuantParameters(proto, outputTensorName); |
| 49 | if (quantParams.weight_size() == 0) { |
| 50 | return; |
| 51 | } |
| 52 | |
| 53 | auto inputParams = quantParams.input(0); |
| 54 | auto outputParams = quantParams.output(0); |
| 55 | auto weightParams = quantParams.weight(0); |
| 56 | auto& tensorDescribe = subgraph ? subgraph->extraTensorDescribe : netT->extraTensorDescribe; |
| 57 | |
| 58 | auto findInDescribe = [&] (int index) { |
| 59 | for (int i = 0; i < tensorDescribe.size(); i++) { |
| 60 | if (tensorDescribe[i]->index == index) { |
| 61 | return true; |
| 62 | } |
| 63 | } |
| 64 | return false; |
| 65 | }; |
| 66 | |
| 67 | if (!findInDescribe(inputIndex)) { |
| 68 | std::unique_ptr<MNN::TensorDescribeT> inDescribe(new MNN::TensorDescribeT); |
| 69 | inDescribe->index = inputIndex; |
| 70 | std::unique_ptr<MNN::TensorQuantInfoT> inputQuantInfo(new MNN::TensorQuantInfoT); |
| 71 | inputQuantInfo->zero = inputParams.zero_point(); |
| 72 | inputQuantInfo->scale = inputParams.scales(0); |
| 73 | inputQuantInfo->min = inputParams.clamp_min(); |
| 74 | inputQuantInfo->max = inputParams.clamp_max(); |
no test coverage detected