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 tensor 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 "nnacl/tensor_c_utils.h"
18 #include "nnacl/nnacl_common.h"
19
CheckAugmentNull(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,const OpParameter * parameter)20 int CheckAugmentNull(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs, size_t outputs_size,
21 const OpParameter *parameter) {
22 NNACL_CHECK_NULL_RETURN_ERR(inputs);
23 NNACL_CHECK_NULL_RETURN_ERR(outputs);
24 for (size_t i = 0; i < inputs_size; i++) {
25 if (inputs[i] == NULL) {
26 return NNACL_NULL_PTR;
27 }
28 }
29 for (size_t i = 0; i < outputs_size; i++) {
30 if (outputs[i] == NULL) {
31 return NNACL_NULL_PTR;
32 }
33 }
34 if (parameter == NULL) {
35 return NNACL_NULL_PTR;
36 }
37 return NNACL_OK;
38 }
39
CheckAugmentNullSize(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,const OpParameter * parameter,size_t inputs_size_obj,size_t outputs_size_obj)40 int CheckAugmentNullSize(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs, size_t outputs_size,
41 const OpParameter *parameter, size_t inputs_size_obj, size_t outputs_size_obj) {
42 int check_ret = CheckAugmentNull(inputs, inputs_size, outputs, outputs_size, parameter);
43 if (check_ret == NNACL_NULL_PTR) {
44 return NNACL_NULL_PTR;
45 }
46 if (inputs_size != inputs_size_obj || outputs_size != outputs_size_obj) {
47 return NNACL_INPUT_TENSOR_ERROR;
48 }
49 return NNACL_OK;
50 }
51
CheckAugmentNullSizeInputTwo(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,const OpParameter * parameter,size_t inputs_size_obj_0,size_t inputs_size_obj_1,size_t outputs_size_obj)52 int CheckAugmentNullSizeInputTwo(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs,
53 size_t outputs_size, const OpParameter *parameter, size_t inputs_size_obj_0,
54 size_t inputs_size_obj_1, size_t outputs_size_obj) {
55 int check_ret = CheckAugmentNull(inputs, inputs_size, outputs, outputs_size, parameter);
56 if (check_ret == NNACL_NULL_PTR) {
57 return NNACL_NULL_PTR;
58 }
59 if ((inputs_size != inputs_size_obj_0 && inputs_size != inputs_size_obj_1) || outputs_size != outputs_size_obj) {
60 return NNACL_INPUT_TENSOR_ERROR;
61 }
62 return NNACL_OK;
63 }
64
CheckAugmentNullInputSize(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,const OpParameter * parameter,size_t inputs_size_obj)65 int CheckAugmentNullInputSize(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs, size_t outputs_size,
66 const OpParameter *parameter, size_t inputs_size_obj) {
67 int check_ret = CheckAugmentNull(inputs, inputs_size, outputs, outputs_size, parameter);
68 if (check_ret == NNACL_NULL_PTR) {
69 return NNACL_NULL_PTR;
70 }
71 if (inputs_size != inputs_size_obj) {
72 return NNACL_INPUT_TENSOR_ERROR;
73 }
74 return NNACL_OK;
75 }
76
CheckAugmentNullOutputSize(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,const OpParameter * parameter,size_t outputs_size_obj)77 int CheckAugmentNullOutputSize(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs, size_t outputs_size,
78 const OpParameter *parameter, size_t outputs_size_obj) {
79 int check_ret = CheckAugmentNull(inputs, inputs_size, outputs, outputs_size, parameter);
80 if (check_ret == NNACL_NULL_PTR) {
81 return NNACL_NULL_PTR;
82 }
83 if (outputs_size != outputs_size_obj) {
84 return NNACL_INPUT_TENSOR_ERROR;
85 }
86 return NNACL_OK;
87 }
88
CheckAugmentWithMinSize(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,const OpParameter * parameter,size_t inputs_size_obj,size_t outputs_size_obj)89 int CheckAugmentWithMinSize(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs, size_t outputs_size,
90 const OpParameter *parameter, size_t inputs_size_obj, size_t outputs_size_obj) {
91 int check_ret = CheckAugmentNull(inputs, inputs_size, outputs, outputs_size, parameter);
92 if (check_ret == NNACL_NULL_PTR) {
93 return NNACL_NULL_PTR;
94 }
95 if (inputs_size < inputs_size_obj || outputs_size < outputs_size_obj) {
96 return NNACL_INPUT_TENSOR_ERROR;
97 }
98 return NNACL_OK;
99 }
100
SetShapeTensor(TensorC * dst,const TensorC * src)101 void SetShapeTensor(TensorC *dst, const TensorC *src) {
102 for (size_t i = 0; i < src->shape_size_; i++) {
103 dst->shape_[i] = src->shape_[i];
104 }
105 dst->shape_size_ = src->shape_size_;
106 }
107
SetShapeArray(TensorC * dst,const int * src,size_t src_size)108 void SetShapeArray(TensorC *dst, const int *src, size_t src_size) {
109 for (size_t i = 0; i < src_size && i < MAX_SHAPE_SIZE; i++) {
110 dst->shape_[i] = src[i];
111 }
112 dst->shape_size_ = src_size;
113 }
114
SetDataTypeFormat(TensorC * dst,const TensorC * src)115 void SetDataTypeFormat(TensorC *dst, const TensorC *src) {
116 dst->format_ = src->format_;
117 dst->data_type_ = src->data_type_;
118 }
119
GetBatch(const TensorC * tensor)120 int GetBatch(const TensorC *tensor) {
121 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
122 return -1;
123 }
124 switch (tensor->format_) {
125 case Format_NHWC:
126 case Format_NHWC4:
127 case Format_NCHW:
128 case Format_NC4HW4:
129 case Format_NC8HW8:
130 case Format_KCHW:
131 case Format_KHWC:
132 case Format_NC:
133 case Format_NC4:
134 return tensor->shape_[kNHWC_N];
135 case Format_HWCK:
136 case Format_CHWK:
137 if (tensor->shape_size_ != DIMENSION_4D) {
138 return -1;
139 }
140 return tensor->shape_[kHWCN_N];
141 case Format_HWKC:
142 if (tensor->shape_size_ != DIMENSION_4D) {
143 return -1;
144 }
145 return tensor->shape_[kHWNC_N];
146 case Format_CKHW:
147 return tensor->shape_[1];
148 default:
149 return -1;
150 }
151 }
GetHeight(const TensorC * tensor)152 int GetHeight(const TensorC *tensor) {
153 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
154 return -1;
155 }
156 switch (tensor->format_) {
157 case Format_NCHW:
158 case Format_KCHW:
159 case Format_CKHW:
160 case Format_NC4HW4:
161 case Format_NC8HW8:
162 if (tensor->shape_size_ != DIMENSION_4D) {
163 return -1;
164 }
165 return tensor->shape_[kNCHW_H];
166 case Format_NHWC:
167 case Format_NHWC4:
168 case Format_KHWC:
169 case Format_CHWK:
170 return tensor->shape_[kNHWC_H];
171 case Format_HWCK:
172 case Format_HWKC:
173 case Format_HW:
174 case Format_HW4:
175 return tensor->shape_[0];
176 default:
177 return -1;
178 }
179 }
GetWidth(const TensorC * tensor)180 int GetWidth(const TensorC *tensor) {
181 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
182 return -1;
183 }
184 switch (tensor->format_) {
185 case Format_NCHW:
186 case Format_KCHW:
187 case Format_CKHW:
188 case Format_NC4HW4:
189 case Format_NC8HW8:
190 if (tensor->shape_size_ != DIMENSION_4D) {
191 return -1;
192 }
193 return tensor->shape_[kNCHW_W];
194 case Format_KHWC:
195 case Format_NHWC:
196 case Format_NHWC4:
197 case Format_CHWK:
198 if (tensor->shape_size_ != DIMENSION_4D) {
199 return -1;
200 }
201 return tensor->shape_[kNHWC_W];
202 case Format_HWCK:
203 case Format_HWKC:
204 case Format_HW:
205 case Format_HW4:
206 return tensor->shape_[1];
207 default:
208 return -1;
209 }
210 }
GetChannel(const TensorC * tensor)211 int GetChannel(const TensorC *tensor) {
212 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
213 return -1;
214 }
215 switch (tensor->format_) {
216 case Format_NCHW:
217 case Format_KCHW:
218 case Format_NC:
219 case Format_NC4:
220 case Format_NC4HW4:
221 case Format_NC8HW8:
222 return tensor->shape_[kNCHW_C];
223 case Format_HWCK:
224 if (tensor->shape_size_ != DIMENSION_4D) {
225 return -1;
226 }
227 return tensor->shape_[kHWCN_C];
228 case Format_HWKC:
229 case Format_NHWC:
230 case Format_NHWC4:
231 case Format_KHWC:
232 if (tensor->shape_size_ != DIMENSION_4D) {
233 return -1;
234 }
235 return tensor->shape_[kNHWC_C];
236 case Format_CKHW:
237 case Format_CHWK:
238 return tensor->shape_[0];
239 default:
240 return -1;
241 }
242 }
243
NnaclSetBatch(TensorC * tensor,int batch)244 void NnaclSetBatch(TensorC *tensor, int batch) {
245 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
246 return;
247 }
248 switch (tensor->format_) {
249 case Format_NHWC:
250 case Format_NHWC4:
251 case Format_NCHW:
252 case Format_NC4HW4:
253 case Format_NC8HW8:
254 case Format_KCHW:
255 case Format_KHWC:
256 case Format_NC:
257 case Format_NC4:
258 tensor->shape_[kNHWC_N] = batch;
259 return;
260 case Format_HWCK:
261 case Format_CHWK:
262 if (tensor->shape_size_ != DIMENSION_4D) {
263 return;
264 }
265 tensor->shape_[kHWCN_N] = batch;
266 return;
267 case Format_HWKC:
268 if (tensor->shape_size_ != DIMENSION_4D) {
269 return;
270 }
271 tensor->shape_[kHWNC_N] = batch;
272 return;
273 case Format_CKHW:
274 tensor->shape_[1] = batch;
275 return;
276 default:
277 return;
278 }
279 }
280
SetHeight(TensorC * tensor,int height)281 void SetHeight(TensorC *tensor, int height) {
282 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
283 return;
284 }
285 switch (tensor->format_) {
286 case Format_NCHW:
287 case Format_KCHW:
288 case Format_CKHW:
289 case Format_NC4HW4:
290 case Format_NC8HW8:
291 if (tensor->shape_size_ != DIMENSION_4D) {
292 return;
293 }
294 tensor->shape_[kNCHW_H] = height;
295 return;
296 case Format_NHWC:
297 case Format_NHWC4:
298 case Format_KHWC:
299 case Format_CHWK:
300 tensor->shape_[kNHWC_H] = height;
301 return;
302 case Format_HWCK:
303 case Format_HWKC:
304 case Format_HW:
305 case Format_HW4:
306 tensor->shape_[0] = height;
307 return;
308 default:
309 return;
310 }
311 }
312
SetWidth(TensorC * tensor,int width)313 void SetWidth(TensorC *tensor, int width) {
314 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
315 return;
316 }
317 switch (tensor->format_) {
318 case Format_NCHW:
319 case Format_KCHW:
320 case Format_CKHW:
321 case Format_NC4HW4:
322 case Format_NC8HW8:
323 if (tensor->shape_size_ != DIMENSION_4D) {
324 return;
325 }
326 tensor->shape_[kNCHW_W] = width;
327 return;
328 case Format_KHWC:
329 case Format_NHWC:
330 case Format_NHWC4:
331 case Format_CHWK:
332 if (tensor->shape_size_ != DIMENSION_4D) {
333 return;
334 }
335 tensor->shape_[kNHWC_W] = width;
336 return;
337 case Format_HWCK:
338 case Format_HWKC:
339 case Format_HW:
340 case Format_HW4:
341 tensor->shape_[1] = width;
342 return;
343 default:
344 return;
345 }
346 }
347
SetChannel(TensorC * tensor,int channel)348 void SetChannel(TensorC *tensor, int channel) {
349 if (tensor->shape_size_ != DIMENSION_4D && tensor->shape_size_ != DIMENSION_2D) {
350 return;
351 }
352 switch (tensor->format_) {
353 case Format_NCHW:
354 case Format_KCHW:
355 case Format_NC:
356 case Format_NC4:
357 case Format_NC4HW4:
358 case Format_NC8HW8:
359 tensor->shape_[kNCHW_C] = channel;
360 return;
361 case Format_HWCK:
362 if (tensor->shape_size_ != DIMENSION_4D) {
363 return;
364 }
365 tensor->shape_[kHWCN_C] = channel;
366 return;
367 case Format_HWKC:
368 case Format_NHWC:
369 case Format_NHWC4:
370 case Format_KHWC:
371 if (tensor->shape_size_ != DIMENSION_4D) {
372 return;
373 }
374 tensor->shape_[kNHWC_C] = channel;
375 return;
376 case Format_CKHW:
377 case Format_CHWK:
378 tensor->shape_[0] = channel;
379 return;
380 default:
381 return;
382 }
383 }
384
GetSize(const TensorC * tensor)385 int GetSize(const TensorC *tensor) {
386 int element_num = GetElementNum(tensor);
387 int data_type_size = (int)DataTypeCSize(tensor->data_type_);
388 return element_num * data_type_size;
389 }
390
GetElementNum(const TensorC * tensor)391 int GetElementNum(const TensorC *tensor) {
392 if (tensor == NULL) {
393 return -1;
394 }
395 if (tensor->shape_size_ == 0) {
396 return 1; // scalar mode
397 }
398 int res = 1;
399 for (size_t i = 0; i < tensor->shape_size_; i++) {
400 NNACL_CHECK_INT_MUL_NOT_OVERFLOW(res, tensor->shape_[i], NNACL_ERRCODE_MUL_OVERFLOW);
401 res = res * tensor->shape_[i];
402 }
403
404 int c = GetChannel(tensor);
405 if (c == 0) {
406 return res;
407 }
408 if (tensor->format_ == Format_NC4HW4) {
409 res = res / c * UP_ROUND(c, C4NUM);
410 }
411 if (tensor->format_ == Format_NC8HW8) {
412 res = res / c * UP_ROUND(c, C8NUM);
413 }
414 return res;
415 }
416
GetDimensionSize(const TensorC * tensor,const size_t index)417 int GetDimensionSize(const TensorC *tensor, const size_t index) {
418 int dim_size = -1;
419 if (index < tensor->shape_size_) {
420 dim_size = tensor->shape_[index];
421 }
422 return dim_size;
423 }
424
IsShapeSame(const TensorC * tensor1,const TensorC * tensor2)425 bool IsShapeSame(const TensorC *tensor1, const TensorC *tensor2) {
426 if (tensor1->shape_size_ != tensor2->shape_size_) {
427 return false;
428 }
429 for (size_t i = 0; i < tensor1->shape_size_; i++) {
430 if (tensor1->shape_[i] != tensor2->shape_[i]) {
431 return false;
432 }
433 }
434 return true;
435 }
436
IsConst(const TensorC * tensor)437 bool IsConst(const TensorC *tensor) {
438 return (tensor->category_ == ConstTensor || tensor->category_ == ConstScalar) && tensor->data_ != NULL;
439 }
440