1 /*
2 * Copyright (C) 2017 The Android Open Source Project
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 "Operations.h"
18 #include "OperationsUtils.h"
19
20 #include "internal/optimized/optimized_ops.h"
21
22 namespace android {
23 namespace nn {
24
25 #define ANDROID_NN_POOLING_PARAMETERS \
26 uint32_t height = getSizeOfDimension(inputShape, 1); \
27 uint32_t width = getSizeOfDimension(inputShape, 2); \
28 uint32_t outHeight = getSizeOfDimension(outputShape, 1); \
29 uint32_t outWidth = getSizeOfDimension(outputShape, 2); \
30 \
31 uint32_t paddingHeight = (uint32_t)padding_top; \
32 uint32_t paddingWidth = (uint32_t)padding_left;
33
averagePoolFloat32(const float * inputData,const Shape & inputShape,int32_t padding_left,int32_t padding_right,int32_t padding_top,int32_t padding_bottom,int32_t stride_width,int32_t stride_height,int32_t filter_width,int32_t filter_height,int32_t activation,float * outputData,const Shape & outputShape)34 bool averagePoolFloat32(const float* inputData, const Shape& inputShape,
35 int32_t padding_left, int32_t padding_right,
36 int32_t padding_top, int32_t padding_bottom,
37 int32_t stride_width, int32_t stride_height,
38 int32_t filter_width, int32_t filter_height, int32_t activation,
39 float* outputData, const Shape& outputShape) {
40
41 ANDROID_NN_POOLING_PARAMETERS
42
43 #define ANDROID_NN_AVERAGE_POOL(activation) \
44 optimized_ops::AveragePool<FusedActivationFunctionType::activation>( \
45 inputData, convertShapeToDims(inputShape), \
46 stride_width, stride_height, paddingWidth, paddingHeight, \
47 filter_width, filter_height, \
48 outputData, convertShapeToDims(outputShape))
49
50 ANDROID_NN_MACRO_DISPATCH(ANDROID_NN_AVERAGE_POOL)
51 #undef ANDROID_NN_AVERAGE_POOL
52
53 return true;
54 }
55
averagePoolQuant8(const uint8_t * inputData,const Shape & inputShape,int32_t padding_left,int32_t padding_right,int32_t padding_top,int32_t padding_bottom,int32_t stride_width,int32_t stride_height,int32_t filter_width,int32_t filter_height,int32_t activation,uint8_t * outputData,const Shape & outputShape)56 bool averagePoolQuant8(const uint8_t* inputData, const Shape& inputShape,
57 int32_t padding_left, int32_t padding_right,
58 int32_t padding_top, int32_t padding_bottom,
59 int32_t stride_width, int32_t stride_height,
60 int32_t filter_width, int32_t filter_height, int32_t activation,
61 uint8_t* outputData, const Shape& outputShape) {
62
63 ANDROID_NN_POOLING_PARAMETERS
64
65 int32_t output_activation_min = 0;
66 int32_t output_activation_max = 0;
67
68 CalculateActivationRangeUint8(activation, outputShape,
69 &output_activation_min,
70 &output_activation_max);
71
72 #define ANDROID_NN_AVERAGE_POOL(activation) \
73 optimized_ops::AveragePool<FusedActivationFunctionType::activation>( \
74 inputData, convertShapeToDims(inputShape), \
75 stride_width, stride_height, paddingWidth, paddingHeight, \
76 filter_width, filter_height, \
77 output_activation_min, output_activation_max, \
78 outputData, convertShapeToDims(outputShape))
79
80 ANDROID_NN_MACRO_DISPATCH(ANDROID_NN_AVERAGE_POOL)
81 #undef ANDROID_NN_AVERAGE_POOL
82
83 return true;
84 }
85
l2PoolFloat32(const float * inputData,const Shape & inputShape,int32_t padding_left,int32_t padding_right,int32_t padding_top,int32_t padding_bottom,int32_t stride_width,int32_t stride_height,int32_t filter_width,int32_t filter_height,int32_t activation,float * outputData,const Shape & outputShape)86 bool l2PoolFloat32(const float* inputData, const Shape& inputShape,
87 int32_t padding_left, int32_t padding_right,
88 int32_t padding_top, int32_t padding_bottom,
89 int32_t stride_width, int32_t stride_height,
90 int32_t filter_width, int32_t filter_height, int32_t activation,
91 float* outputData, const Shape& outputShape) {
92
93 ANDROID_NN_POOLING_PARAMETERS
94
95 #define ANDROID_NN_L2_POOL(activation) \
96 optimized_ops::L2Pool<FusedActivationFunctionType::activation>( \
97 inputData, convertShapeToDims(inputShape), \
98 stride_width, stride_height, paddingWidth, paddingHeight, \
99 filter_width, filter_height, \
100 outputData, convertShapeToDims(outputShape))
101
102 ANDROID_NN_MACRO_DISPATCH(ANDROID_NN_L2_POOL)
103 #undef ANDROID_NN_L2_POOL
104
105 return true;
106 }
107
maxPoolFloat32(const float * inputData,const Shape & inputShape,int32_t padding_left,int32_t padding_right,int32_t padding_top,int32_t padding_bottom,int32_t stride_width,int32_t stride_height,int32_t filter_width,int32_t filter_height,int32_t activation,float * outputData,const Shape & outputShape)108 bool maxPoolFloat32(const float* inputData, const Shape& inputShape,
109 int32_t padding_left, int32_t padding_right,
110 int32_t padding_top, int32_t padding_bottom,
111 int32_t stride_width, int32_t stride_height,
112 int32_t filter_width, int32_t filter_height, int32_t activation,
113 float* outputData, const Shape& outputShape) {
114
115 ANDROID_NN_POOLING_PARAMETERS
116
117 #define ANDROID_NN_MAX_POOL(activation) \
118 optimized_ops::MaxPool<FusedActivationFunctionType::activation>( \
119 inputData, convertShapeToDims(inputShape), \
120 stride_width, stride_height, paddingWidth, paddingHeight, \
121 filter_width, filter_height, \
122 outputData, convertShapeToDims(outputShape))
123
124 ANDROID_NN_MACRO_DISPATCH(ANDROID_NN_MAX_POOL)
125 #undef ANDROID_NN_MAX_POOL
126
127 return true;
128 }
129
maxPoolQuant8(const uint8_t * inputData,const Shape & inputShape,int32_t padding_left,int32_t padding_right,int32_t padding_top,int32_t padding_bottom,int32_t stride_width,int32_t stride_height,int32_t filter_width,int32_t filter_height,int32_t activation,uint8_t * outputData,const Shape & outputShape)130 bool maxPoolQuant8(const uint8_t* inputData, const Shape& inputShape,
131 int32_t padding_left, int32_t padding_right,
132 int32_t padding_top, int32_t padding_bottom,
133 int32_t stride_width, int32_t stride_height,
134 int32_t filter_width, int32_t filter_height, int32_t activation,
135 uint8_t* outputData, const Shape& outputShape) {
136
137 ANDROID_NN_POOLING_PARAMETERS
138
139 int32_t output_activation_min = 0;
140 int32_t output_activation_max = 0;
141
142 CalculateActivationRangeUint8(activation, outputShape,
143 &output_activation_min,
144 &output_activation_max);
145
146 #define ANDROID_NN_MAX_POOL(activation) \
147 optimized_ops::MaxPool<FusedActivationFunctionType::activation>( \
148 inputData, convertShapeToDims(inputShape), \
149 stride_width, stride_height, paddingWidth, paddingHeight, \
150 filter_width, filter_height, \
151 output_activation_min, output_activation_max, \
152 outputData, convertShapeToDims(outputShape))
153
154 ANDROID_NN_MACRO_DISPATCH(ANDROID_NN_MAX_POOL)
155 #undef ANDROID_NN_MAX_POOL
156
157 return true;
158 }
159
160 #undef ANDROID_NN_POOLING_PARAMETERS
161 } // namespace nn
162 } // namespace android
163