• 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/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