美文网首页
MNN 构建后端

MNN 构建后端

作者: i_1312 | 来源:发表于2022-12-19 21:46 被阅读0次

    添加一个后端需要去继承Backend抽象类,并实现所有纯虚函数。

    //类函数执行流程:构造 -> onCreate -> onResizeBegin -> onResizeEnd -> onAcquire -> onCopyBuffer -> onExecuteBegin -> onExecuteEnd -> onCopyBuffer -> onClearBuffer
    class NPUBackend : public Backend {
        public:
            //NPUBackend构造函数,NPURuntime用于存放cache参赛以及附加编译选项
            NPUBackend(const NPURuntime* runtime);
            virtual ~NPUBackend();
            //onCreate : 根据传入op的类型,创建对应npu算子
            virtual Execution* onCreate(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs, const MNN::Op* op) override;
            //推理前准备函数
            virtual void onExecuteBegin() const override;
            //推理后处理函数
            virtual void onExecuteEnd() const override;
            //内存申请统一函数
            virtual Backend::MemObj* onAcquire(const Tensor* tensor, StorageType storageType) override;
            //清除缓存
            virtual bool onClearBuffer() override;
            //内存拷贝函数(通常用于数据格式转换)
            virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override;
            //维度计算/内存申请前准备
            virtual void onResizeBegin() override;
            //计算维度/内存申请后处理
            virtual void onResizeEnd() override;
    }
    

    onCreate函数
    Backend需要通过onCreate为为每一个op创建出exection,一个exection通常代表一个算子实例:
    它会去后端算子实现中查找算子,如果没有找到对应的算子,则使用CPU的后端

    Execution* NPUBackend::onCreate(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs, const MNN::Op* op) {
    //获取已注册的npu算子map
        auto map = getCreatorMap();
        auto iter = map->find(op->type());
            
        if (iter == map->end()) {
            MNN_ERROR("map not find !!! \n");
            if(op != nullptr){
                if(op->name() != nullptr){
                    MNN_PRINT("[NPU] Don't support type %d, %s\n", op->type(), op->name()->c_str());
                }
            }
            return nullptr;
        }
        //当查找到npu支持该算子,即创建exection
        auto exe = iter->second->onCreate(inputs, outputs, op, this);
    
        if (nullptr == exe) {
            MNN_ERROR("nullptr == exe !!! \n");
            if(op != nullptr){
                if(op->name() != nullptr){
                    MNN_PRINT("[NPU] The Creator Don't support type %d, %s\n", op->type(), op->name()->c_str());
                }
            }
            return nullptr;
        }
    
        return exe;
    }
    

    onCopyBuffer

    拷贝可能在backend内部,也可能在npu backend与CPU backend之间。拷贝需要处理Tensor间的布局转换,相同布局时,可以直接拷贝数据;不同布局,如NHWCNC4HW4,则一般需要做特殊转换。该部分工作需要在onCopyBuffer函数中实现。具体参考:https://github.com/alibaba/MNN/blob/master/source/backend/hiai/backend/NPUBackend.cpp

    2.4 onResizeEnd
    用于对构图后的模型,进行编译,生产npu可执行模型文件

    void NPUBackend::onResizeEnd() {
        bulidIRModelAndLoad();
    }
    

    2.5 onExecuteEnd
    模型推理代码,即npu sdk提供的推理api在此添加

    1. 新增算子
      3.1 实现
      每个新增算子都要继承Execution,并重写两个函数onResize,onExecute。onExecute用于mnn到npu参数转换,并重新构图。onExecute在npu没用到,只需返回NO_ERROR;
    class NPUCommonExecution : public Execution {
        public:
        NPUCommonExecution(Backend *backend, const Op *op);
        virtual ~NPUCommonExecution() = default;
        virtual ErrorCode onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) override;
        virtual ErrorCode onExecute(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) override;
    };
    
    ErrorCode NPUActivation::onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {
        
        auto opName = mOp->name()->str();
        
        auto xOp = mNpuBackend->getInputOps(mOp);
    
        shared_ptr<ge::op::Activation> relu(new ge::op::Activation(opName + "_relu"));
        (*relu)
            .set_input_x(*xOp.get())
            .set_attr_coef(.000000) 
            .set_attr_mode(mType);
        mNpuBackend->setOutputOps(mOp, {relu}, outputs);
    
        return NO_ERROR;
    }
    

    相关文章

      网友评论

          本文标题:MNN 构建后端

          本文链接:https://www.haomeiwen.com/subject/sroeqdtx.html