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
22namespace android {
23namespace 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
34bool 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
57bool 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
83bool 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
106bool 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
129bool 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