1 /**
2 * Copyright 2020-2021 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/npu/npu_converter_utils.h"
18 #include "src/litert/delegate/npu/op/npu_op.h"
19 namespace mindspore::lite {
20 #define C4NUM 4
21 #define C8NUM 8
22 #ifdef ENABLE_ARM
Float32ToFloat16(const float * __restrict input,float16_t * __restrict output,int number)23 void Float32ToFloat16(const float *__restrict input, float16_t *__restrict output, int number) {
24 int i = 0;
25 #ifdef ENABLE_ARM64
26 int count = (number & ~(C8NUM - 1));
27 for (; i < count; i += C8NUM) {
28 float32x4_t in1 = vld1q_f32(input + i);
29 float16x4_t out1 = vcvt_f16_f32(in1);
30 float32x4_t in2 = vld1q_f32(input + i + C4NUM);
31 float16x4_t out2 = vcvt_f16_f32(in2);
32 float16x8_t out = vcombine_f16(out1, out2);
33 vst1q_f16(output + i, out);
34 }
35 #endif
36 for (; i < number; ++i) {
37 output[i] = static_cast<float16_t>(input[i]);
38 }
39 }
40
Float16ToFloat32(const float16_t * __restrict input,float * __restrict output,int number)41 void Float16ToFloat32(const float16_t *__restrict input, float *__restrict output, int number) {
42 int i = 0;
43 #ifdef ENABLE_ARM64
44 int count = number & ~(C8NUM - 1);
45 for (; i < count; i += C8NUM) {
46 float16x8_t in = vld1q_f16(input + i);
47 float16x4_t in1 = vget_low_f16(in);
48 float16x4_t in2 = vget_high_f16(in);
49 float32x4_t out1 = vcvt_f32_f16(in1);
50 vst1q_f32(output + i, out1);
51 float32x4_t out2 = vcvt_f32_f16(in2);
52 vst1q_f32(output + i + C4NUM, out2);
53 }
54 #endif
55 for (; i < number; ++i) {
56 output[i] = static_cast<float>(input[i]);
57 }
58 }
59 #endif
60
ConverterToNPUShape(const std::vector<int64_t> & src_shape,bool is_expand_4d)61 ge::Shape ConverterToNPUShape(const std::vector<int64_t> &src_shape, bool is_expand_4d) {
62 std::vector<int64_t> shapes;
63 shapes.reserve(src_shape.size());
64 for (int i = 0; i < src_shape.size(); i++) {
65 shapes.push_back(src_shape[i]);
66 }
67 if (is_expand_4d) {
68 if (shapes.size() == 1) {
69 return ge::Shape({1, shapes[0], 1, 1});
70 } else {
71 for (int i = src_shape.size(); i < NPU_SHAPE_SIZE; i++) {
72 shapes.push_back(1);
73 }
74 }
75 }
76 return ge::Shape({shapes});
77 }
78
ConverterToNPUFormat(schema::Format format)79 ge::Format ConverterToNPUFormat(schema::Format format) {
80 ge::Format ge_format;
81 switch (format) {
82 case schema::Format_NCHW:
83 ge_format = ge::FORMAT_NCHW;
84 break;
85 case schema::Format_NHWC:
86 case schema::Format_KHWC:
87 ge_format = ge::FORMAT_NHWC;
88 break;
89 default:
90 MS_LOG(ERROR) << "Unsupported format:" << format;
91 // use unused format to indicate errors.
92 ge_format = ge::FORMAT_ND;
93 break;
94 }
95 return ge_format;
96 }
97
ConverterToNPUDataType(DataType type_id)98 ge::DataType ConverterToNPUDataType(DataType type_id) {
99 ge::DataType data_type;
100 switch (type_id) {
101 case DataType::kNumberTypeFloat32:
102 case DataType::kNumberTypeFloat16:
103 data_type = ge::DT_FLOAT;
104 break;
105 case DataType::kNumberTypeInt8:
106 data_type = ge::DT_INT8;
107 break;
108 case DataType::kNumberTypeUInt8:
109 data_type = ge::DT_UINT8;
110 break;
111 case DataType::kNumberTypeInt16:
112 data_type = ge::DT_INT16;
113 break;
114 case DataType::kNumberTypeInt32:
115 data_type = ge::DT_INT32;
116 break;
117 case DataType::kNumberTypeUInt32:
118 data_type = ge::DT_UINT32;
119 break;
120 case DataType::kNumberTypeBool:
121 data_type = ge::DT_BOOL;
122 break;
123 default:
124 data_type = ge::DT_UNDEFINED;
125 break;
126 }
127 return data_type;
128 }
129
ConverterToNPUData(const mindspore::MSTensor & src,const std::string & name)130 hiai::op::Data *ConverterToNPUData(const mindspore::MSTensor &src, const std::string &name) {
131 auto data = new (std::nothrow) hiai::op::Data(name);
132 if (data == nullptr) {
133 MS_LOG(ERROR) << "new data failed.";
134 return data;
135 }
136 ge::TensorDesc tensor_desc(ConverterToNPUShape(src.Shape()), ge::FORMAT_NCHW, ConverterToNPUDataType(src.DataType()));
137 data->update_input_desc_x(tensor_desc);
138 return data;
139 }
140
ConverterToNPUTensor(mindspore::MSTensor src,bool is_expand_4d)141 std::shared_ptr<ge::Tensor> ConverterToNPUTensor(mindspore::MSTensor src, bool is_expand_4d) {
142 std::shared_ptr<ge::Tensor> ge_tensor = std::make_shared<ge::Tensor>();
143 if (ge_tensor == nullptr) {
144 MS_LOG(ERROR) << "new ge_tensor failed.";
145 return nullptr;
146 }
147 ge::TensorDesc tensor_desc(ConverterToNPUShape(src.Shape(), is_expand_4d), ge::FORMAT_NCHW,
148 ConverterToNPUDataType(src.DataType()));
149
150 ge_tensor->SetTensorDesc(tensor_desc);
151
152 if (src.Data() != nullptr) {
153 if (src.DataType() == DataType::kNumberTypeFloat16) {
154 #ifdef ENABLE_ARM
155 auto fp32_data = malloc(src.ElementNum() * sizeof(float));
156 if (fp32_data == nullptr) {
157 MS_LOG(ERROR) << "malloc failed for fp32 data";
158 return nullptr;
159 }
160 Float16ToFloat32(reinterpret_cast<float16_t *>(src.MutableData()), reinterpret_cast<float *>(fp32_data),
161 src.ElementNum());
162 ge_tensor->SetData(reinterpret_cast<const uint8_t *>(fp32_data), src.ElementNum() * sizeof(float));
163 free(fp32_data);
164 fp32_data = nullptr;
165 #else
166 MS_LOG(ERROR) << "This platform does not support fp16.";
167 return nullptr;
168 #endif
169 } else {
170 ge_tensor->SetData(reinterpret_cast<const uint8_t *>(src.MutableData()), src.DataSize());
171 }
172 }
173 return ge_tensor;
174 }
175
176 // mode : Either 0 (product), 1 (sum), 2 (max), 3 (mean). Defaults to 1 (sum).
ConverterToNPUEltwiseMode(schema::EltwiseMode mode)177 int ConverterToNPUEltwiseMode(schema::EltwiseMode mode) {
178 int mode_num = 1;
179 switch (mode) {
180 case schema::EltwiseMode_PROD:
181 mode_num = 0;
182 break;
183 case schema::EltwiseMode_SUM:
184 mode_num = 1;
185 break;
186 case schema::EltwiseMode_MAXIMUM:
187 mode_num = 2;
188 break;
189 default:
190 MS_LOG(ERROR) << "Unsupported Eltwise mode.";
191 }
192 return mode_num;
193 }
194
TransFormAxis(int axis)195 int TransFormAxis(int axis) {
196 switch (axis) {
197 case NHWC_N:
198 return NCHW_N;
199 case NHWC_H:
200 return NCHW_H;
201 case NHWC_W:
202 return NCHW_W;
203 case NHWC_C:
204 return NCHW_C;
205 default:
206 return NCHW_INVALID;
207 }
208 }
209
ConverterToNPUActivationMode(schema::ActivationType type)210 int ConverterToNPUActivationMode(schema::ActivationType type) {
211 switch (type) {
212 case schema::ActivationType_SIGMOID:
213 return SIGMOID;
214 case schema::ActivationType_RELU:
215 return RELU;
216 case schema::ActivationType_TANH:
217 return TANH;
218 case schema::ActivationType_LEAKY_RELU:
219 return P_RELU;
220 case schema::ActivationType_HSIGMOID:
221 return HARD_SIGMOID;
222 case schema::ActivationType_RELU6:
223 return RELU6;
224 case schema::ActivationType_ELU:
225 return ELU;
226 case schema::ActivationType_GELU:
227 return GELU;
228 default:
229 return ACTIVATION_INVALID;
230 }
231 }
232 } // namespace mindspore::lite
233