1 // 2 // SparseConvolutionTiledExecutor 3 // MNN 4 // 5 // Created by MNN on 2021/04/06. 6 // Copyright © 2018-2021 Alibaba Group Holding Limited. 7 // 8 9 #ifndef SparseConvolutionTiledExecutor_hpp 10 #define SparseConvolutionTiledExecutor_hpp 11 12 #include <functional> 13 #include "backend/cpu/CPUConvolution.hpp" 14 #include "ConvolutionTiledExecutor.hpp" 15 // Tiled Slide Window or Im2Col + GEMM 16 #define SPARSITY_THRESHOLD (0.3f) 17 namespace MNN { 18 19 20 class SparseConvolutionTiledImpl : public ConvolutionTiledImpl { 21 public: SparseConvolutionTiledImpl(const Convolution2DCommon * common,const SparseCommon * sparseCommon,Backend * b)22 SparseConvolutionTiledImpl(const Convolution2DCommon *common, const SparseCommon* sparseCommon, Backend *b) : mSparseCommon{sparseCommon}, ConvolutionTiledImpl(common, b) { 23 mSparseBlockOC = mSparseCommon->args()->LookupByKey("sparseBlockOC")->i(); 24 } 25 virtual ~SparseConvolutionTiledImpl() = default; 26 virtual ErrorCode onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs, Tensor* NNZMap, Tensor* dataOffsetMap); 27 void getPackParameter(int* eP, int* lP, int* hP, const CoreFunctions* core) override; 28 public: 29 const SparseCommon* mSparseCommon; 30 int mSparseBlockOC; 31 }; 32 33 class SparseConvolutionTiledExecutor : public ConvolutionTiledExecutor { 34 public: 35 SparseConvolutionTiledExecutor(const Convolution2DCommon *common, Backend *b, const float *originWeight, 36 size_t originWeightSize, const SparseCommon* sparseCommon, const float *bias, size_t biasSize); 37 38 SparseConvolutionTiledExecutor(std::shared_ptr<CPUConvolution::Resource> res, std::shared_ptr<Tensor> NNZMapSharePtr, std::shared_ptr<Tensor> dataOffsetMapSharePtr, 39 const Convolution2DCommon *common, const SparseCommon* sparseCommon, Backend *b); 40 virtual ~SparseConvolutionTiledExecutor(); 41 onExecute(const std::vector<Tensor * > & inputs,const std::vector<Tensor * > & outputs)42 virtual ErrorCode onExecute(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) override { 43 return mProxy->onExecute(inputs, outputs); 44 } onResize(const std::vector<Tensor * > & inputs,const std::vector<Tensor * > & outputs)45 virtual ErrorCode onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) override { 46 mInputs = {inputs[0], mResource->mWeight.get(), mResource->mBias.get()}; 47 return mProxy->onResize(mInputs, outputs, mNNZMap.get(), mDataOffsetMap.get()); 48 } 49 virtual bool onClone(Backend *bn, const Op *op, Execution **dst) override; 50 51 void initWeight(float *dest, unsigned int *NNZMap, int *dataOffsetMap, int sparseBlockOC, const float *source, 52 float *cache, int depth, int outputCount, int kernelSize, int eP, size_t weightNNZElement, 53 size_t weightBlockNumber, const CoreFunctions *function); 54 shouldUseSparseConvolution(size_t originWeightSize,const SparseCommon * sparseCommon)55 static bool shouldUseSparseConvolution(size_t originWeightSize, const SparseCommon* sparseCommon) { 56 return originWeightSize - sparseCommon->args()->LookupByKey("NNZElement")->i() >= originWeightSize * SPARSITY_THRESHOLD; 57 } 58 protected: 59 std::shared_ptr<SparseConvolutionTiledImpl> mProxy; 60 std::shared_ptr<Tensor> mNNZMap; 61 std::shared_ptr<Tensor> mDataOffsetMap; 62 }; 63 } // namespace MNN 64 65 #endif /* SparseConvolutionTiledExecutor_hpp */