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