1eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang/* 2eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * Copyright (C) 2017 The Android Open Source Project 3eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * 4eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * you may not use this file except in compliance with the License. 6eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * You may obtain a copy of the License at 7eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * 8eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * http://www.apache.org/licenses/LICENSE-2.0 9eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * 10eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * Unless required by applicable law or agreed to in writing, software 11eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * distributed under the License is distributed on an "AS IS" BASIS, 12eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * See the License for the specific language governing permissions and 14eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang * limitations under the License. 15eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang */ 16eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 17eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang#include "Operations.h" 18d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang#include "CpuOperationUtils.h" 19eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 20d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang#include "tensorflow/contrib/lite/kernels/internal/optimized/optimized_ops.h" 21eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 22eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangnamespace android { 23eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangnamespace nn { 24eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 2527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang#define ANDROID_NN_POOLING_PARAMETERS \ 2627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t height = getSizeOfDimension(inputShape, 1); \ 2727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t width = getSizeOfDimension(inputShape, 2); \ 2827e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t outHeight = getSizeOfDimension(outputShape, 1); \ 2927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t outWidth = getSizeOfDimension(outputShape, 2); \ 3027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang \ 316cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang uint32_t paddingHeight = (uint32_t)padding_top; \ 326cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang uint32_t paddingWidth = (uint32_t)padding_left; 3327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 34eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangbool averagePoolFloat32(const float* inputData, const Shape& inputShape, 356cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 366cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 376cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 38eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang int32_t filter_width, int32_t filter_height, int32_t activation, 39eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang float* outputData, const Shape& outputShape) { 4027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 4127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_POOLING_PARAMETERS 4227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 43d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang float output_activation_min, output_activation_max; 44d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang CalculateActivationRangeFloat(activation, &output_activation_min, 45d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang &output_activation_max); 4627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 47d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::AveragePool( 48d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), 49d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, paddingWidth, paddingHeight, 50d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filter_width, filter_height, 51d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 52d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 5327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 5427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang return true; 5527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang} 5627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 5727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wangbool averagePoolQuant8(const uint8_t* inputData, const Shape& inputShape, 586cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 596cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 606cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 6127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t filter_width, int32_t filter_height, int32_t activation, 6227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint8_t* outputData, const Shape& outputShape) { 6327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 6427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_POOLING_PARAMETERS 6527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 6627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_activation_min = 0; 6727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_activation_max = 0; 6827e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 6927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang CalculateActivationRangeUint8(activation, outputShape, 7027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang &output_activation_min, 7127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang &output_activation_max); 72eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 73d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::AveragePool( 74d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), 75d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, paddingWidth, paddingHeight, 76d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filter_width, filter_height, 77d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 78d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 79eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 80eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang return true; 81eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} 82eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 83eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangbool l2PoolFloat32(const float* inputData, const Shape& inputShape, 846cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 856cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 866cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 87eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang int32_t filter_width, int32_t filter_height, int32_t activation, 88eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang float* outputData, const Shape& outputShape) { 8927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 9027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_POOLING_PARAMETERS 91eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 92d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang float output_activation_min, output_activation_max; 93d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang CalculateActivationRangeFloat(activation, &output_activation_min, 94d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang &output_activation_max); 95eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 96d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::L2Pool( 97d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), 98d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, paddingWidth, paddingHeight, 99d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filter_width, filter_height, 100d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 101d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 102eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 103eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang return true; 104eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} 105eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 106eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangbool maxPoolFloat32(const float* inputData, const Shape& inputShape, 1076cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 1086cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 1096cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 110eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang int32_t filter_width, int32_t filter_height, int32_t activation, 111eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang float* outputData, const Shape& outputShape) { 11227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 11327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_POOLING_PARAMETERS 114eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 115d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang float output_activation_min, output_activation_max; 116d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang CalculateActivationRangeFloat(activation, &output_activation_min, 117d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang &output_activation_max); 118eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 119d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::MaxPool( 120d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), 121d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, paddingWidth, paddingHeight, 122d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filter_width, filter_height, 123d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 124d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 125eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 126eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang return true; 127eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} 128eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 12927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wangbool maxPoolQuant8(const uint8_t* inputData, const Shape& inputShape, 1306cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 1316cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 1326cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 13327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t filter_width, int32_t filter_height, int32_t activation, 13427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint8_t* outputData, const Shape& outputShape) { 13527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 13627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_POOLING_PARAMETERS 13727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 13827e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_activation_min = 0; 13927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_activation_max = 0; 14027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 14127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang CalculateActivationRangeUint8(activation, outputShape, 14227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang &output_activation_min, 14327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang &output_activation_max); 14427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 145d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::MaxPool( 146d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), 147d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, paddingWidth, paddingHeight, 148d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filter_width, filter_height, 149d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 150d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 15127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 15227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang return true; 15327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang} 154eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 15527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang#undef ANDROID_NN_POOLING_PARAMETERS 156eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} // namespace nn 157eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} // namespace android 158