1 /**
2 * Copyright 2021-2022 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/fp32/div_fp32.h"
18 #include <math.h>
19 #include "nnacl/fp32/arithmetic_fp32.h"
20 #include "nnacl/div_fp32_simd.h"
21
ElementOptDiv(const float * in0,const float * in1,float * out,int size,bool first_scalar)22 int ElementOptDiv(const float *in0, const float *in1, float *out, int size, bool first_scalar) {
23 int index = 0;
24
25 if (first_scalar) {
26 SIMD_RUN_NO_SCALAR(ElementOptDivNum0, index, in0, in1, out, size);
27
28 for (; index < size; index++) {
29 out[index] = in0[0] / in1[index];
30 }
31 } else {
32 SIMD_RUN_NO_SCALAR(ElementOptDivNum1, index, in0, in1, out, size);
33 for (; index < size; index++) {
34 out[index] = in0[index] / in1[0];
35 }
36 }
37 return NNACL_OK;
38 }
39
ElementOptDivRelu(const float * in0,const float * in1,float * out,int size,bool first_scalar)40 int ElementOptDivRelu(const float *in0, const float *in1, float *out, int size, bool first_scalar) {
41 int index = 0;
42 if (first_scalar) {
43 SIMD_RUN_NO_SCALAR(ElementOptDivReluNum0, index, in0, in1, out, size);
44
45 for (; index < size; index++) {
46 out[index] = in0[0] / in1[index];
47 out[index] = out[index] > 0 ? out[index] : 0;
48 }
49 } else {
50 SIMD_RUN_NO_SCALAR(ElementOptDivReluNum1, index, in0, in1, out, size);
51
52 for (; index < size; index++) {
53 out[index] = in0[index] / in1[0];
54 out[index] = out[index] > 0 ? out[index] : 0;
55 }
56 }
57 return NNACL_OK;
58 }
59
ElementOptDivRelu6(const float * in0,const float * in1,float * out,int size,bool first_scalar)60 int ElementOptDivRelu6(const float *in0, const float *in1, float *out, int size, bool first_scalar) {
61 int index = 0;
62
63 if (first_scalar) {
64 SIMD_RUN_NO_SCALAR(ElementOptDivRelu6Num0, index, in0, in1, out, size);
65
66 for (; index < size; index++) {
67 out[index] = MSMIN(MSMAX(in0[0] / in1[index], RELU6_MIN_VAL), RELU6_MAX_VAL);
68 }
69 } else {
70 SIMD_RUN_NO_SCALAR(ElementOptDivRelu6Num1, index, in0, in1, out, size);
71
72 for (; index < size; index++) {
73 out[index] = MSMIN(MSMAX(in0[index] / in1[0], RELU6_MIN_VAL), RELU6_MAX_VAL);
74 }
75 }
76 return NNACL_OK;
77 }
78
ElementOptDivInt(const int32_t * in0,const int32_t * in1,int32_t * out,int size,bool first_scalar)79 int ElementOptDivInt(const int32_t *in0, const int32_t *in1, int32_t *out, int size, bool first_scalar) {
80 int index = 0;
81
82 if (first_scalar) {
83 SIMD_RUN_NO_SCALAR(ElementOptDivIntNum0, index, in0, in1, out, size);
84
85 for (; index < size; index++) {
86 NNACL_CHECK_ZERO_RETURN_ERR(in1[index] != 0);
87 out[index] = in0[0] / in1[index];
88 }
89 } else {
90 NNACL_CHECK_ZERO_RETURN_ERR(in1[0] != 0);
91
92 SIMD_RUN_NO_SCALAR(ElementOptDivIntNum1, index, in0, in1, out, size);
93
94 for (; index < size; index++) {
95 out[index] = in0[index] / in1[0];
96 }
97 }
98 return NNACL_OK;
99 }
100
BroadcastDiv(const float * in0,const float * in1,float * tile_in0,float * tile_in1,float * out,int size,ArithmeticParameter * param)101 int BroadcastDiv(const float *in0, const float *in1, float *tile_in0, float *tile_in1, float *out, int size,
102 ArithmeticParameter *param) {
103 TileDimensionsFp32(in0, in1, tile_in0, tile_in1, param);
104 return ElementDiv(tile_in0, tile_in1, out, size);
105 }
106
ElementDiv(const float * in0,const float * in1,float * out,int size)107 int ElementDiv(const float *in0, const float *in1, float *out, int size) {
108 int index = 0;
109
110 SIMD_RUN_NO_SCALAR(ElementDiv, index, in0, in1, out, size);
111 for (; index < size; index++) {
112 out[index] = in0[index] / in1[index];
113 }
114 return NNACL_OK;
115 }
116
ElementDivRelu(const float * in0,const float * in1,float * out,int size)117 int ElementDivRelu(const float *in0, const float *in1, float *out, int size) {
118 int index = 0;
119
120 SIMD_RUN_NO_SCALAR(ElementDivRelu, index, in0, in1, out, size);
121 for (; index < size; index++) {
122 float res = in0[index] / in1[index];
123 out[index] = res > 0 ? res : 0;
124 }
125 return NNACL_OK;
126 }
127
ElementDivRelu6(const float * in0,const float * in1,float * out,int size)128 int ElementDivRelu6(const float *in0, const float *in1, float *out, int size) {
129 int index = 0;
130
131 SIMD_RUN_NO_SCALAR(ElementDivRelu6, index, in0, in1, out, size);
132 for (; index < size; index++) {
133 out[index] = MSMIN(MSMAX(in0[index] / in1[index], RELU6_MIN_VAL), RELU6_MAX_VAL);
134 }
135 return NNACL_OK;
136 }
137