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 "CpuOperationUtils.h"
19 
20 #include "tensorflow/contrib/lite/kernels/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     float output_activation_min, output_activation_max;
44     CalculateActivationRangeFloat(activation, &output_activation_min,
45                                   &output_activation_max);
46 
47     tflite::optimized_ops::AveragePool(
48             inputData, convertShapeToDims(inputShape),
49             stride_width, stride_height, paddingWidth, paddingHeight,
50             filter_width, filter_height,
51             output_activation_min, output_activation_max,
52             outputData, convertShapeToDims(outputShape));
53 
54     return true;
55 }
56 
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)57 bool averagePoolQuant8(const uint8_t* inputData, const Shape& inputShape,
58                        int32_t padding_left, int32_t padding_right,
59                        int32_t padding_top, int32_t padding_bottom,
60                        int32_t stride_width, int32_t stride_height,
61                        int32_t filter_width, int32_t filter_height, int32_t activation,
62                        uint8_t* outputData, const Shape& outputShape) {
63 
64     ANDROID_NN_POOLING_PARAMETERS
65 
66     int32_t output_activation_min = 0;
67     int32_t output_activation_max = 0;
68 
69     CalculateActivationRangeUint8(activation, outputShape,
70                                   &output_activation_min,
71                                   &output_activation_max);
72 
73     tflite::optimized_ops::AveragePool(
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     return true;
81 }
82 
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)83 bool l2PoolFloat32(const float* inputData, const Shape& inputShape,
84                    int32_t padding_left, int32_t padding_right,
85                    int32_t padding_top, int32_t padding_bottom,
86                    int32_t stride_width, int32_t stride_height,
87                    int32_t filter_width, int32_t filter_height, int32_t activation,
88                    float* outputData, const Shape& outputShape) {
89 
90     ANDROID_NN_POOLING_PARAMETERS
91 
92     float output_activation_min, output_activation_max;
93     CalculateActivationRangeFloat(activation, &output_activation_min,
94                                   &output_activation_max);
95 
96     tflite::optimized_ops::L2Pool(
97             inputData, convertShapeToDims(inputShape),
98             stride_width, stride_height, paddingWidth, paddingHeight,
99             filter_width, filter_height,
100             output_activation_min, output_activation_max,
101             outputData, convertShapeToDims(outputShape));
102 
103     return true;
104 }
105 
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)106 bool maxPoolFloat32(const float* inputData, const Shape& inputShape,
107                     int32_t padding_left, int32_t padding_right,
108                     int32_t padding_top, int32_t padding_bottom,
109                     int32_t stride_width, int32_t stride_height,
110                     int32_t filter_width, int32_t filter_height, int32_t activation,
111                     float* outputData, const Shape& outputShape) {
112 
113     ANDROID_NN_POOLING_PARAMETERS
114 
115     float output_activation_min, output_activation_max;
116     CalculateActivationRangeFloat(activation, &output_activation_min,
117                                   &output_activation_max);
118 
119     tflite::optimized_ops::MaxPool(
120             inputData, convertShapeToDims(inputShape),
121             stride_width, stride_height, paddingWidth, paddingHeight,
122             filter_width, filter_height,
123             output_activation_min, output_activation_max,
124             outputData, convertShapeToDims(outputShape));
125 
126     return true;
127 }
128 
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)129 bool maxPoolQuant8(const uint8_t* inputData, const Shape& inputShape,
130                    int32_t padding_left, int32_t padding_right,
131                    int32_t padding_top, int32_t padding_bottom,
132                    int32_t stride_width, int32_t stride_height,
133                    int32_t filter_width, int32_t filter_height, int32_t activation,
134                    uint8_t* outputData, const Shape& outputShape) {
135 
136     ANDROID_NN_POOLING_PARAMETERS
137 
138     int32_t output_activation_min = 0;
139     int32_t output_activation_max = 0;
140 
141     CalculateActivationRangeUint8(activation, outputShape,
142                                   &output_activation_min,
143                                   &output_activation_max);
144 
145     tflite::optimized_ops::MaxPool(
146             inputData, convertShapeToDims(inputShape),
147             stride_width, stride_height, paddingWidth, paddingHeight,
148             filter_width, filter_height,
149             output_activation_min, output_activation_max,
150             outputData, convertShapeToDims(outputShape));
151 
152     return true;
153 }
154 
155 #undef ANDROID_NN_POOLING_PARAMETERS
156 }  // namespace nn
157 }  // namespace android
158