• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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