• 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 #include <include/errorcode.h>
17 #include "nnrt_model_kernel.h"
18 #include "nnrt_allocator.h"
19 #include "litert/cxx_api/tensor/tensor_impl.h"
20 
21 namespace mindspore{
22 namespace {
23 constexpr auto kDynamicDims = "DynamicDims";
24 }
25 
Prepare()26 int NNRTModelKernel::Prepare() {
27   auto nnrt_allocator = lite::NNRTAllocator::GetInstance();
28   if (nnrt_allocator == nullptr) {
29     MS_LOG(ERROR) << "Get NNRTAllocator failed";
30     return lite::RET_NULL_PTR;
31   }
32   nnrt_allocator->SetDeviceId(nnrt_device_info_.device_id_);
33   for (size_t i = 0; i < inputs_.size(); i++) {
34     inputs_[i].SetAllocator(nnrt_allocator);
35   }
36   for (size_t i = 0; i < outputs_.size(); i++) {
37     outputs_[i].SetAllocator(nnrt_allocator);
38   }
39   return lite::RET_OK;
40 }
41 
ReSize()42 int NNRTModelKernel::ReSize() {
43   const auto &extensions = nnrt_device_info_.extensions_;
44   auto iter = std::find_if(extensions.begin(), extensions.end(), [](const lite::Extension &extension) {
45     return extension.name == kDynamicDims;
46   });
47   if (iter != extensions.end() && !iter->value.empty()) {
48     return lite::RET_OK;
49   }
50   MS_LOG(ERROR) << "NNRT only support the resize function when DynamicDims is enabled.";
51   return lite::RET_ERROR;
52 }
53 
Execute()54 int NNRTModelKernel::Execute() {
55   MS_CHECK_TRUE_RET(this->outputs().empty() != true, lite::RET_ERROR);
56   zero_copy_ = IS_NNRT_ALLOCATOR(this->outputs()[Index0].allocator());
57 
58   if (!zero_copy_) {
59     FreeNNTensor();
60   }
61   nn_input_tensors_.clear();
62   nn_output_tensors_.clear();
63   nn_input_tensor_descs_.clear();
64   nn_output_tensor_descs_.clear();
65 
66   lite::STATUS ret_val = SetInputs();
67   if (ret_val != lite::RET_OK) {
68     MS_LOG(ERROR) << "NNRTModelKernel SetInputs failed, STATUS is " << ret_val;
69     return ret_val;
70   }
71   ret_val = SetOutputs();
72   if (ret_val != lite::RET_OK) {
73     MS_LOG(ERROR) << "NNRTModelKernel SetOutputs failed, STATUS is " << ret_val;
74     return ret_val;
75   }
76   MS_LOG(INFO) << "Running NNRtModel Kernel...";
77   OH_NN_ReturnCode ret_code;
78   ret_code = OH_NNExecutor_RunSync(oh_nn_executor_, nn_input_tensors_.data(), nn_input_tensors_.size(),
79                                    nn_output_tensors_.data(), nn_output_tensors_.size());
80 
81   if (ret_code != OH_NN_SUCCESS) {
82     MS_LOG(ERROR) << "OH_NNExecutor_RunSync Run failed, OH_NN_ReturnCode = " << ret_code;
83     return lite::RET_ERROR;
84   }
85   MS_LOG(INFO) << "Run NNRtModel Kernel success.";
86 
87   return lite::RET_OK;
88 }
89 
SetInputs()90 int NNRTModelKernel::SetInputs() {
91   if (!zero_copy_) {
92     OH_NN_ReturnCode ret{OH_NN_FAILED};
93     size_t nn_input_count = 0;
94     ret = OH_NNExecutor_GetInputCount(oh_nn_executor_, &nn_input_count);
95     if (ret != OH_NN_SUCCESS) {
96       MS_LOG(ERROR) << "OH_NNExecutor_GetInputCount failed.";
97       return lite::RET_ERROR;
98     }
99     if (nn_input_count != inputs_.size()) {
100       MS_LOG(ERROR) << "input count is not equal between ms and nnrt.";
101       return lite::RET_ERROR;
102     }
103     for (size_t i = 0; i < nn_input_count; i++) {
104       NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateInputTensorDesc(oh_nn_executor_, i);
105       if (tensor_desc_tmp == nullptr) {
106         MS_LOG(ERROR) << "OH_NNExecutor_CreateInputTensorDesc failed, i = " << i;
107         return lite::RET_ERROR;
108       }
109       nn_input_tensor_descs_.emplace_back(tensor_desc_tmp);
110       NN_Tensor *tensor_tmp = OH_NNTensor_Create(nnrt_device_info_.device_id_, tensor_desc_tmp);
111       if (tensor_tmp == nullptr) {
112         MS_LOG(ERROR) << "OH_NNTensor_Create input failed, i = " << i;
113         return lite::RET_ERROR;
114       }
115       nn_input_tensors_.emplace_back(tensor_tmp);
116       void *nn_data = OH_NNTensor_GetDataBuffer(nn_input_tensors_[i]);
117       size_t tensor_size;
118       ret = OH_NNTensorDesc_GetByteSize(tensor_desc_tmp, &tensor_size);
119       if (ret != OH_NN_SUCCESS || tensor_size != inputs_[i].DataSize()) {
120         MS_LOG(ERROR) << "NN_Tensor size is not equal to MSTensor, i = " << i;
121         return lite::RET_ERROR;
122       }
123       memcpy(nn_data, inputs_[i].MutableData(), inputs_[i].DataSize());
124     }
125   } else {
126     for (size_t i = 0; i < inputs_.size(); i++) {
127       if (inputs_[i].allocator() == nullptr) {
128         MS_LOG(ERROR) << "NNRTAllocator is nullptr, i = " << i;
129         return lite::RET_ERROR;
130       }
131       void *data = inputs_[i].MutableData();
132       NN_Tensor *tensor_tmp = reinterpret_cast<lite::NNRTAllocator *>(inputs_[i].allocator().get())->GetNNTensor(data);
133       if (tensor_tmp == nullptr) {
134         MS_LOG(ERROR) << "NNRTAllocator GetNNTensor failed, i = " << i;
135         return lite::RET_ERROR;
136       }
137       nn_input_tensors_.emplace_back(tensor_tmp);
138     }
139   }
140   return lite::RET_OK;
141 }
142 
SetOutputs()143 int NNRTModelKernel::SetOutputs() {
144   if (!zero_copy_) {
145     OH_NN_ReturnCode ret{OH_NN_FAILED};
146     size_t nn_output_count = 0;
147     ret = OH_NNExecutor_GetOutputCount(oh_nn_executor_, &nn_output_count);
148     if (ret != OH_NN_SUCCESS) {
149       MS_LOG(ERROR) << "OH_NNExecutor_GetOutputCount failed.";
150       return lite::RET_ERROR;
151     }
152     if (nn_output_count != outputs_.size()) {
153       MS_LOG(ERROR) << "output count is not equal between ms and nnrt.";
154       return lite::RET_ERROR;
155     }
156     for (size_t i = 0; i < nn_output_count; i++) {
157       NN_TensorDesc *tensor_desc_tmp = OH_NNExecutor_CreateOutputTensorDesc(oh_nn_executor_, i);
158       if (tensor_desc_tmp == nullptr) {
159         MS_LOG(ERROR) << "OH_NNExecutor_CreateOutputTensorDesc failed, i = " << i;
160         return lite::RET_ERROR;
161       }
162       nn_output_tensor_descs_.emplace_back(tensor_desc_tmp);
163       NN_Tensor *tensor_tmp = OH_NNTensor_Create(nnrt_device_info_.device_id_, tensor_desc_tmp);
164       if (tensor_tmp == nullptr) {
165         MS_LOG(ERROR) << "OH_NNTensor_Create output failed, i = " << i;
166         return lite::RET_ERROR;
167       }
168       nn_output_tensors_.emplace_back(tensor_tmp);
169       auto data = OH_NNTensor_GetDataBuffer(nn_output_tensors_[i]);
170       reinterpret_cast<LiteTensorImpl *>(outputs_[i].impl().get())->lite_tensor()->FreeData();
171       outputs_[i].SetData(data, false);
172     }
173   } else {
174     for (size_t i = 0; i < outputs_.size(); i++) {
175       if (outputs_[i].allocator() == nullptr) {
176         MS_LOG(ERROR) << "NNRTAllocator is nullptr, i = " << i;
177         return lite::RET_ERROR;
178       }
179       void *data = outputs_[i].MutableData();
180       NN_Tensor *tensor_tmp = reinterpret_cast<lite::NNRTAllocator *>(outputs_[i].allocator().get())->GetNNTensor(data);
181       if (tensor_tmp == nullptr) {
182         MS_LOG(ERROR) << "NNRTAllocator GetNNTensor failed, i = " << i;
183         return lite::RET_ERROR;
184       }
185       nn_output_tensors_.emplace_back(tensor_tmp);
186     }
187   }
188   return lite::RET_OK;
189 }
190 
FreeNNTensor()191 void NNRTModelKernel::FreeNNTensor() {
192   for (size_t i = 0; i < nn_input_tensors_.size(); i++) {
193     OH_NNTensor_Destroy(&nn_input_tensors_[i]);
194     OH_NNTensorDesc_Destroy(&nn_input_tensor_descs_[i]);
195   }
196   for (size_t i = 0; i < nn_output_tensors_.size(); i++) {
197     OH_NNTensor_Destroy(&nn_output_tensors_[i]);
198     OH_NNTensorDesc_Destroy(&nn_output_tensor_descs_[i]);
199   }
200 }
201 
202 }  // namespace mindspore
203