• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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