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 */