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 #include "src/litert/delegate/nnapi/op/nnapi_op.h"
18 #include <unordered_map>
19 #include "src/litert/delegate/nnapi/nnapi_utils.h"
20 #include "src/tensor.h"
21 #include "nnacl/op_base.h"
22
23 namespace mindspore {
24 namespace lite {
25 namespace {
26 std::unordered_map<schema::PrimitiveType, OperationCode> common_op_type = {
27 {schema::PrimitiveType_Rsqrt, ANEURALNETWORKS_RSQRT},
28 {schema::PrimitiveType_Equal, ANEURALNETWORKS_EQUAL},
29 {schema::PrimitiveType_ExpFusion, ANEURALNETWORKS_EXP},
30 {schema::PrimitiveType_Floor, ANEURALNETWORKS_FLOOR}};
31 } // namespace
32
ConvertInOutQuantSymmToASymm()33 int NNAPIOp::ConvertInOutQuantSymmToASymm() {
34 for (auto input : in_tensors_) {
35 ConverTensorQuantSymmToASymm(&input);
36 }
37
38 for (auto output : out_tensors_) {
39 ConverTensorQuantSymmToASymm(&output);
40 }
41 return RET_OK;
42 }
43
InitNNAPIOpInOut(const std::vector<mindspore::MSTensor> & all_tensors)44 int NNAPIOp::InitNNAPIOpInOut(const std::vector<mindspore::MSTensor> &all_tensors) {
45 input_indices_.clear();
46 output_indices_.clear();
47 for (auto input : in_tensors_) {
48 auto itr = std::find(all_tensors.begin(), all_tensors.end(), input);
49 MS_CHECK_TRUE_RET(itr != all_tensors.end(), RET_ERROR);
50 input_indices_.push_back(itr - all_tensors.begin());
51 }
52 for (auto output : out_tensors_) {
53 auto itr = std::find(all_tensors.begin(), all_tensors.end(), output);
54 MS_CHECK_TRUE_RET(itr != all_tensors.end(), RET_ERROR);
55 output_indices_.push_back(itr - all_tensors.begin());
56 }
57 return RET_OK;
58 }
59
AddTensorToNNAPIModel(ANeuralNetworksModel * nnapi_model,std::vector<mindspore::MSTensor> * all_tensors,MSTensorInfo tensor_info)60 int NNAPIOp::AddTensorToNNAPIModel(ANeuralNetworksModel *nnapi_model, std::vector<mindspore::MSTensor> *all_tensors,
61 MSTensorInfo tensor_info) {
62 auto tensor = MSTensor::CreateTensor(tensor_info.name_, tensor_info.type_, tensor_info.shape_, tensor_info.data_,
63 tensor_info.data_len_);
64 if (tensor == nullptr) {
65 MS_LOG(ERROR) << "Create bias tensor failed.";
66 return RET_ERROR;
67 }
68 if (AddNNAPIOperand(nnapi_model, *tensor, static_cast<int>(all_tensors->size())) != RET_OK) {
69 MS_LOG(ERROR) << "Add NNAPI operand failed.";
70 delete tensor;
71 return RET_ERROR;
72 }
73 input_indices_.push_back(all_tensors->size());
74 all_tensors->push_back(*tensor);
75 op_attribute_tensors_.push_back(tensor);
76 return RET_OK;
77 }
78
AddOpToNNAPIModel(ANeuralNetworksModel * nnapi_model,std::vector<mindspore::MSTensor> * all_tensors)79 int NNAPICommon::AddOpToNNAPIModel(ANeuralNetworksModel *nnapi_model, std::vector<mindspore::MSTensor> *all_tensors) {
80 MS_ASSERT(nnapi_model != nullptr && all_tensors != nullptr);
81 MS_CHECK_TRUE_RET(common_op_type.find(type_) != common_op_type.end(), RET_ERROR);
82 OperationCode node_type = common_op_type.at(type_);
83 if (InitNNAPIOpInOut(*all_tensors) != RET_OK) {
84 MS_LOG(ERROR) << "InitNNAPINodeInfo failed.";
85 return RET_ERROR;
86 }
87
88 if (nnapi_->ANeuralNetworksModel_addOperation(nnapi_model, node_type, input_indices_.size(), input_indices_.data(),
89 output_indices_.size(),
90 output_indices_.data()) != ANEURALNETWORKS_NO_ERROR) {
91 MS_LOG(ERROR) << "Add operation to NNAPI model failed: " << op_name_;
92 return RET_ERROR;
93 }
94 return RET_OK;
95 }
96 } // namespace lite
97 } // namespace mindspore
98