| 23 | return sparsity > thresholds[std::min(std::max(sparseBlockOC, 0), (int)thresholds.size() - 1)]; |
| 24 | } |
| 25 | void AddSparseInfo(std::unique_ptr<MNN::OpT>& op, Compression::Pipeline proto) { |
| 26 | auto prune_algo_type = MNN::SparseAlgo_RANDOM; |
| 27 | int sparseBlockOC = 1; |
| 28 | int sparseBlockKernel = 1; |
| 29 | |
| 30 | for (const auto& algo : proto.algo()) { |
| 31 | if (algo.type() == Compression::CompressionAlgo::PRUNE) { |
| 32 | auto prune_type = algo.prune_params().type(); |
| 33 | prune_algo_type = MNN::SparseAlgo(prune_type); |
| 34 | if (prune_type == Compression::PruneParams_PruneType_SIMD_OC) { |
| 35 | sparseBlockOC = algo.prune_params().simd_oc_pruner_params().oc_blocks(0); |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | const auto opType = op->type; |
| 41 | switch (opType) { |
| 42 | case MNN::OpType_Convolution: |
| 43 | case MNN::OpType_ConvolutionDepthwise: { |
| 44 | auto param = op->main.AsConvolution2D(); |
| 45 | if (param->weight.empty()) { |
| 46 | return; |
| 47 | } |
| 48 | |
| 49 | size_t weightSize = param->weight.size(); |
| 50 | size_t biasSize = param->bias.size(); |
| 51 | size_t weightNNZElement, weightBlockNumber = 0; |
| 52 | CommonCompute::statisticWeightSparsity(weightNNZElement, weightBlockNumber, param->weight.data(), biasSize, weightSize / biasSize, sparseBlockOC); |
| 53 | float sparsity = 1. - double(weightNNZElement) / weightSize; |
| 54 | if (!shouldUseSparseConvolution(sparsity, sparseBlockOC)) { |
| 55 | return; |
| 56 | } |
| 57 | // MNN_PRINT(" opname [%s] sparsity is:%f, use sparse\n", op->name.c_str(), sparsity); |
| 58 | |
| 59 | MNN::AttributeT* arg1(new MNN::AttributeT); |
| 60 | arg1->key = "sparseBlockOC"; |
| 61 | arg1->i = sparseBlockOC; |
| 62 | |
| 63 | MNN::AttributeT* arg2(new MNN::AttributeT); |
| 64 | arg2->key = "sparseBlockKernel"; |
| 65 | arg2->i = sparseBlockKernel; |
| 66 | |
| 67 | MNN::AttributeT* arg3(new MNN::AttributeT); |
| 68 | arg3->key = "NNZElement"; |
| 69 | arg3->i = weightNNZElement; |
| 70 | |
| 71 | MNN::AttributeT* arg4(new MNN::AttributeT); |
| 72 | arg4->key = "blockNumber"; |
| 73 | arg4->i = weightBlockNumber; |
| 74 | |
| 75 | flatbuffers::FlatBufferBuilder builder; |
| 76 | std::vector<flatbuffers::Offset<MNN::Attribute>> argsVector; |
| 77 | auto sparseArg1 = MNN::CreateAttribute(builder, arg1); |
| 78 | auto sparseArg2 = MNN::CreateAttribute(builder, arg2); |
| 79 | auto sparseArg3 = MNN::CreateAttribute(builder, arg3); |
| 80 | auto sparseArg4 = MNN::CreateAttribute(builder, arg4); |
| 81 | |
| 82 | argsVector.emplace_back(sparseArg1); |
no test coverage detected