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