1 /** 2 * Copyright 2022 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINDSPORE_LITE_SRC_LITERT_DELEGATE_NNAPI_NNAPI_DELEGATE_H_ 18 #define MINDSPORE_LITE_SRC_LITERT_DELEGATE_NNAPI_NNAPI_DELEGATE_H_ 19 20 #include <string> 21 #include <memory> 22 #include <vector> 23 #include <queue> 24 #include <unordered_map> 25 #include <utility> 26 #include "include/api/delegate.h" 27 #include "src/litert/delegate/nnapi/nnapi_subgraph.h" 28 #include "src/litert/delegate/nnapi/op/nnapi_op.h" 29 30 namespace mindspore { 31 namespace lite { 32 class NNAPIDelegate : public Delegate { 33 public: NNAPIDelegate()34 NNAPIDelegate() : Delegate() {} NNAPIDelegate(bool relax_fp32_to_fp16,bool only_use_acc_device,bool disable_cpu_device,const std::vector<std::string> & specified_devices)35 explicit NNAPIDelegate(bool relax_fp32_to_fp16, bool only_use_acc_device, bool disable_cpu_device, 36 const std::vector<std::string> &specified_devices) 37 : Delegate(), 38 relax_fp32_to_fp16_(relax_fp32_to_fp16), 39 only_use_acc_device_(only_use_acc_device), 40 disable_cpu_device_(disable_cpu_device), 41 specified_devices_(std::move(specified_devices)) {} 42 ~NNAPIDelegate()43 ~NNAPIDelegate() override{}; 44 45 Status Init() override; 46 47 Status Build(DelegateModel<schema::Primitive> *model) override; 48 49 void ReplaceNodes(const std::shared_ptr<LiteDelegateGraph> &graph) override; 50 51 private: 52 template <typename T> FindReadyKernels(std::vector<T * > * kernels,std::vector<T * > * ready_kernels)53 STATUS FindReadyKernels(std::vector<T *> *kernels, std::vector<T *> *ready_kernels) { 54 MS_ASSERT(kernels != nullptr && ready_kernels != nullptr); 55 std::queue<T *> tmp_kernels; 56 std::vector<mindspore::MSTensor> visited_tensor; 57 58 std::function<bool(T *)> is_kernel_ready = [&visited_tensor](T *kernel) { 59 return std::all_of(kernel->inputs().begin(), kernel->inputs().end(), [&visited_tensor](MSTensor input) { 60 return input.IsConst() || 61 std::find(visited_tensor.begin(), visited_tensor.end(), input) != visited_tensor.end(); 62 }); 63 }; 64 65 // initialize the visited_tensor map. 66 for (const auto &input : inputs_) { 67 visited_tensor.push_back(input); 68 } 69 for (auto ready_kernel : sorted_kernels_) { 70 for (const auto &output : ready_kernel->outputs()) { 71 visited_tensor.push_back(output); 72 } 73 } 74 for (auto kernel : *kernels) { 75 MS_CHECK_TRUE_RET(kernel != nullptr, RET_ERROR); 76 if (is_kernel_ready(kernel)) { 77 tmp_kernels.push(kernel); 78 ready_kernels->push_back(kernel); 79 kernels->erase(std::find(kernels->begin(), kernels->end(), kernel)); 80 break; 81 } 82 } 83 84 while (!tmp_kernels.empty()) { 85 auto tmp_kernel = tmp_kernels.front(); 86 tmp_kernels.pop(); 87 for (const auto &output : tmp_kernel->outputs()) { 88 visited_tensor.push_back(output); 89 } 90 for (auto itr = kernels->begin(); itr != kernels->end();) { 91 if (is_kernel_ready(*itr)) { 92 tmp_kernels.push(*itr); 93 ready_kernels->push_back(*itr); 94 kernels->erase(itr); 95 } else { 96 itr++; 97 } 98 } 99 } 100 return RET_OK; 101 } 102 103 NNAPISubGraph *CreateNNAPISubGraph(DelegateModel<schema::Primitive> *model, std::vector<NNAPIOp *> *condidate_ops); 104 105 private: 106 bool relax_fp32_to_fp16_ = true; 107 bool only_use_acc_device_ = false; 108 bool disable_cpu_device_ = false; 109 std::vector<std::string> specified_devices_; 110 111 std::vector<mindspore::MSTensor> inputs_; 112 std::vector<kernel::Kernel *> sorted_kernels_; 113 std::vector<kernel::Kernel *> remained_kernels_; 114 std::vector<NNAPISubGraph *> nnapi_kernels_; 115 std::unordered_map<schema::PrimitiveType, NNAPIGetOp> op_func_lists_; 116 std::vector<ANeuralNetworksDevice *> devices_; 117 }; 118 } // namespace lite 119 } // namespace mindspore 120 121 #endif // MINDSPORE_LITE_SRC_LITERT_DELEGATE_NNAPI_NNAPI_DELEGATE_H_ 122