• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020 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 #include <queue>
17 #include <memory>
18 #include "src/mindrt_executor.h"
19 #include "src/lite_mindrt.h"
20 #include "include/errorcode.h"
21 #include "src/common/tensor_util.h"
22 #include "nnacl/base/cast_base.h"
23 
24 namespace mindspore::lite {
PrepareInputData(const std::vector<kernel::LiteKernel * > & kernels,const std::vector<Tensor * > & inputs)25 int MindrtExecutor::PrepareInputData(const std::vector<kernel::LiteKernel *> &kernels,
26                                      const std::vector<Tensor *> &inputs) {
27   for (size_t j = 0; j < kernels.size(); ++j) {
28     auto in_tensor_size = kernels[j]->in_tensors().size();
29     for (size_t k = 0; k < in_tensor_size; ++k) {
30       auto tensor = kernels[j]->in_tensors()[k];
31       if (!tensor->IsGraphInput()) {
32         continue;
33       }
34       size_t idx = std::find(inputs.begin(), inputs.end(), tensor) - inputs.begin();
35       if (idx == inputs.size()) {
36         MS_LOG(ERROR) << "The input is not found.";
37         return RET_ERROR;
38       }
39       auto data = std::make_shared<OpData<Tensor>>(op_actors_[j]->GetAID(), inputs.at(idx), static_cast<int>(k));
40       if (data == nullptr) {
41         MS_LOG(ERROR) << "new opdata failed.";
42         return RET_NULL_PTR;
43       }
44       input_data_.emplace_back(data);
45     }
46   }
47   return RET_OK;
48 }
49 
PrepareOutputData(const std::vector<kernel::LiteKernel * > & kernels,const std::vector<Tensor * > & outputs)50 int MindrtExecutor::PrepareOutputData(const std::vector<kernel::LiteKernel *> &kernels,
51                                       const std::vector<Tensor *> &outputs) {
52   for (size_t i = 0; i < outputs.size(); ++i) {
53     Tensor *graph_output_tensor = outputs[i];
54     if (graph_output_tensor->IsGraphInput()) {
55       continue;
56     }
57     auto current_output_map =
58       std::find_if(output_tensor_map_->begin(), output_tensor_map_->end(), [&](const auto output_map_tensor) {
59         if (graph_output_tensor == output_map_tensor.second) {
60           return true;
61         }
62         return false;
63       });
64     MS_ASSERT(current_output_map != output_tensor_map_->end());
65     Tensor *subgraph_output_tensor = current_output_map->first;
66 
67     for (size_t j = 0; j < kernels.size(); ++j) {
68       auto out_tensor_size = kernels[j]->out_tensors().size();
69       for (size_t k = 0; k < out_tensor_size; ++k) {
70         if (subgraph_output_tensor != kernels[j]->out_tensors()[k]) {
71           continue;
72         }
73         auto data =
74           std::make_shared<OpData<Tensor>>(op_actors_[j]->GetAID(), subgraph_output_tensor, static_cast<int>(k));
75         if (data == nullptr) {
76           MS_LOG(ERROR) << "new opdata failed.";
77           return RET_NULL_PTR;
78         }
79         op_actors_[j]->AddResultIndex(output_data_.size());
80         output_data_.emplace_back(data);
81       }
82     }
83   }
84   return RET_OK;
85 }
86 
Resize(const std::vector<mindspore::tensor::MSTensor * > & inputs,const std::vector<std::vector<int>> & dims)87 int MindrtExecutor::Resize(const std::vector<mindspore::tensor::MSTensor *> &inputs,
88                            const std::vector<std::vector<int>> &dims) {
89   for (auto actor : op_actors_) {
90     actor->ResizeGraphInput(inputs, dims);
91   }
92   return RET_OK;
93 }
94 
Prepare(const std::vector<kernel::LiteKernel * > & kernels,const std::vector<Tensor * > & inputs,const std::vector<Tensor * > & outputs,const lite::InnerContext * ctx)95 int MindrtExecutor::Prepare(const std::vector<kernel::LiteKernel *> &kernels, const std::vector<Tensor *> &inputs,
96                             const std::vector<Tensor *> &outputs, const lite::InnerContext *ctx) {
97   MS_ASSERT(ctx != nullptr);
98   ctx_ = ctx;
99   auto ret = MindrtInit();
100   if (ret != RET_OK) {
101     MS_LOG(ERROR) << "MindrtInit failed";
102     return ret;
103   }
104   op_actors_ = CreateOpActor(kernels, ctx);
105   if (op_actors_.size() != kernels.size()) {
106     MS_LOG(ERROR) << "CreateOpActor failed";
107     return RET_ERROR;
108   }
109 
110   ret = PrepareInputData(kernels, inputs);
111   if (ret != RET_OK) {
112     MS_LOG(ERROR) << "PrepareInputData failed";
113     return ret;
114   }
115 
116   ret = PrepareOutputData(kernels, outputs);
117   if (ret != RET_OK) {
118     MS_LOG(ERROR) << "PrepareOutputData failed";
119     return ret;
120   }
121 
122   for (auto actor : op_actors_) {
123     ret = actor->LiteActorInit(&op_actors_);
124     if (ret != RET_OK) {
125       MS_LOG(ERROR) << "LiteActorInit failed, actor aid: " << actor->GetAID();
126       return ret;
127     }
128   }
129 
130   return RET_OK;
131 }
132 
TransferGraphOutput()133 void MindrtExecutor::TransferGraphOutput() {
134   for (auto tensor_map : *output_tensor_map_) {
135     auto dst_tensor = tensor_map.second;
136     auto src_tensor = tensor_map.first;
137     dst_tensor->set_shape(src_tensor->shape());
138     /* dst tensor free in FreeOutputTensor */
139 
140     if (src_tensor->data_type() == kNumberTypeFloat16) {
141       dst_tensor->MallocData();
142       Fp16ToFloat32(reinterpret_cast<uint16_t *>(src_tensor->MutableData()),
143                     reinterpret_cast<float *>(dst_tensor->data()), dst_tensor->ElementsNum());
144     } else {
145       dst_tensor->set_data(src_tensor->data());
146       src_tensor->set_data(nullptr);
147     }
148     src_tensor->DecRefCount();
149   }
150   return;
151 }
152 
FreeOutputTensor()153 void MindrtExecutor::FreeOutputTensor() {
154   for (auto tensor_map : *output_tensor_map_) {
155     auto src_tensor = tensor_map.first;
156     auto dst_tensor = tensor_map.second;
157     if (dst_tensor->allocator() != nullptr) {
158       dst_tensor->FreeData();
159     } else {
160       if (dst_tensor->data_type() == src_tensor->data_type()) {
161         /* user set graph-output-tensor from outside */
162         src_tensor->set_data(dst_tensor->data());
163         src_tensor->set_own_data(false);
164         src_tensor->set_allocator(nullptr);
165       }
166     }
167   }
168   return;
169 }
170 
Run(const std::vector<Tensor * > & in_tensors,const std::vector<Tensor * > & out_tensors,const std::vector<kernel::LiteKernel * > & kernels,const KernelCallBack & before,const KernelCallBack & after)171 int MindrtExecutor::Run(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
172                         const std::vector<kernel::LiteKernel *> &kernels, const KernelCallBack &before,
173                         const KernelCallBack &after) {
174   CHECK_NULL_RETURN(ctx_);
175   auto thread_pool = ctx_->thread_pool();
176   CHECK_NULL_RETURN(thread_pool);
177   if (ctx_->delegate == nullptr) {
178     thread_pool->SetSpinCountMaxValue();
179   }
180 
181   FreeOutputTensor();
182 
183   auto ret = MindrtRun<Tensor>(input_data_, &output_data_, &before, &after);
184   if (ret != RET_OK) {
185     MS_LOG(ERROR) << "MindrtRun failed";
186     return ret;
187   }
188 
189   TransferGraphOutput();
190 
191   thread_pool->SetSpinCountMinValue();
192   return RET_OK;
193 }
194 }  // namespace mindspore::lite
195