1 /**
2 * Copyright 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 "nnacl/infer/prior_box_infer.h"
18 #include <math.h>
19 #include "nnacl/infer/infer_register.h"
20 #include "nnacl/tensor_c_utils.h"
21
PriorBoxInferShape(const TensorC * const * inputs,size_t inputs_size,TensorC ** outputs,size_t outputs_size,OpParameter * parameter)22 int PriorBoxInferShape(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs, size_t outputs_size,
23 OpParameter *parameter) {
24 int check_ret = CheckAugmentWithMinSize(inputs, inputs_size, outputs, outputs_size, parameter, 1, 1);
25 if (check_ret != NNACL_OK) {
26 return check_ret;
27 }
28
29 const TensorC *input = inputs[0];
30 TensorC *output = outputs[0];
31 output->data_type_ = kNumberTypeFloat32;
32 output->format_ = input->format_;
33 if (!InferFlag(inputs, inputs_size)) {
34 return NNACL_INFER_INVALID;
35 }
36 float different_aspect_ratios[MAX_SHAPE_SIZE * 2 + 1]; // NOTE: flip double the number
37 different_aspect_ratios[0] = 1.0;
38 int32_t different_aspect_ratios_size = 1;
39
40 PriorBoxParameter *param = (PriorBoxParameter *)parameter;
41 float *aspect_ratios = param->aspect_ratios;
42 if (aspect_ratios == NULL) {
43 return NNACL_NULL_PTR;
44 }
45 int32_t aspect_ratios_size = param->aspect_ratios_size;
46 NNACL_CHECK_TRUE_RET(aspect_ratios_size <= MAX_SHAPE_SIZE, NNACL_ERR);
47 for (int32_t i = 0; i < aspect_ratios_size; i++) {
48 float ratio = aspect_ratios[i];
49 if (fabsf(ratio) < EPSILON_VALUE) {
50 return NNACL_ERR;
51 }
52
53 bool exist = false;
54 for (int32_t j = 0; j < different_aspect_ratios_size; j++) {
55 if (fabsf(ratio - different_aspect_ratios[j]) < EPSILON_VALUE) {
56 exist = true;
57 break;
58 }
59 }
60 if (!exist) {
61 different_aspect_ratios[different_aspect_ratios_size] = ratio;
62 different_aspect_ratios_size++;
63 if (param->flip) {
64 different_aspect_ratios[different_aspect_ratios_size] = 1.0f / ratio;
65 different_aspect_ratios_size++;
66 }
67 }
68 }
69
70 int32_t min_sizes_size = param->min_sizes_size;
71 int32_t max_sizes_size = param->max_sizes_size;
72 int32_t num_priors_box = min_sizes_size * different_aspect_ratios_size + max_sizes_size;
73 const int kPriorBoxPoints = 4;
74 const int kPriorBoxN = 1;
75 const int kPriorBoxW = 1;
76 const int kPriorBoxC = 2;
77
78 int32_t h = GetHeight(input) * GetWidth(input) * num_priors_box * kPriorBoxPoints;
79 output->shape_size_ = 4;
80 output->shape_[0] = kPriorBoxN;
81 output->shape_[1] = h;
82 output->shape_[2] = kPriorBoxW;
83 output->shape_[3] = kPriorBoxC;
84 return NNACL_OK;
85 }
86
87 REG_INFER(PriorBox, PrimType_PriorBox, PriorBoxInferShape)
88