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/depthwiseconv_float.h" 21d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang#include "tensorflow/contrib/lite/kernels/internal/optimized/depthwiseconv_uint8.h" 22eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 23eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangnamespace android { 24eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangnamespace nn { 25eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 2627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang#define ANDROID_NN_DEPTHWISE_CONV_PARAMETERS \ 2727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t height = getSizeOfDimension(inputShape, 1); \ 2827e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t width = getSizeOfDimension(inputShape, 2); \ 2927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t filterHeight = getSizeOfDimension(filterShape, 1); \ 3027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t filterWidth = getSizeOfDimension(filterShape, 2); \ 3127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t outHeight = getSizeOfDimension(outputShape, 1); \ 3227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t outWidth = getSizeOfDimension(outputShape, 2); \ 3327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang \ 346cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang uint32_t paddingHeight = (uint32_t)padding_top; \ 356cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang uint32_t paddingWidth = (uint32_t)padding_left; 3627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 37eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wangbool depthwiseConvFloat32(const float* inputData, const Shape& inputShape, 38eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang const float* filterData, const Shape& filterShape, 39eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang const float* biasData, const Shape& biasShape, 406cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 416cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 426cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 43eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang int32_t depth_multiplier, int32_t activation, 44eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang float* outputData, const Shape& outputShape) { 4527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 4627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_DEPTHWISE_CONV_PARAMETERS 47eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 48d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang float output_activation_min, output_activation_max; 49d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang CalculateActivationRangeFloat(activation, &output_activation_min, 50d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang &output_activation_max); 51eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 52d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::DepthwiseConv( 53d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), 54d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filterData, convertShapeToDims(filterShape), 55d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang biasData, convertShapeToDims(biasShape), 56d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, 57d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang paddingWidth, paddingHeight, depth_multiplier, 58d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 59d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 60eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 61eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang return true; 62eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} 63eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang 6427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 6527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wangbool depthwiseConvQuant8(const uint8_t* inputData, const Shape& inputShape, 6627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang const uint8_t* filterData, const Shape& filterShape, 6727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang const int32_t* biasData, const Shape& biasShape, 686cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_left, int32_t padding_right, 696cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t padding_top, int32_t padding_bottom, 706cd685f64bd82c003b8d0943fc6b7b8e0730b939Miao Wang int32_t stride_width, int32_t stride_height, 7127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t depth_multiplier, int32_t activation, 7227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint8_t* outputData, const Shape& outputShape) { 7327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 7427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang ANDROID_NN_DEPTHWISE_CONV_PARAMETERS 7527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 7627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang float real_multiplier = 0.0; 7727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_multiplier = 0; 7827e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_shift = 0; 7927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_activation_min = 0; 8027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang int32_t output_activation_max = 0; 8127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 82be2b22578baf949d7be42ba002cee94304daf53cMiao Wang 83be2b22578baf949d7be42ba002cee94304daf53cMiao Wang if (!GetQuantizedConvolutionMultipler(inputShape, filterShape, biasShape, 84be2b22578baf949d7be42ba002cee94304daf53cMiao Wang outputShape, &real_multiplier) || 85be2b22578baf949d7be42ba002cee94304daf53cMiao Wang !QuantizeMultiplierSmallerThanOne(real_multiplier, &output_multiplier, 86be2b22578baf949d7be42ba002cee94304daf53cMiao Wang &output_shift)) { 87be2b22578baf949d7be42ba002cee94304daf53cMiao Wang return false; 88be2b22578baf949d7be42ba002cee94304daf53cMiao Wang } 8927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang CalculateActivationRangeUint8(activation, outputShape, 9027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang &output_activation_min, 9127e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang &output_activation_max); 9227e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 9327e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t inputOffset = -inputShape.offset; 9427e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t filterOffset = -filterShape.offset; 9527e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang uint32_t outputOffset = outputShape.offset; 96d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang 97d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang tflite::optimized_ops::DepthwiseConv( 98d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang inputData, convertShapeToDims(inputShape), inputOffset, 99d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang filterData, convertShapeToDims(filterShape), filterOffset, 100d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang biasData, convertShapeToDims(biasShape), 101d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang stride_width, stride_height, 102d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang paddingWidth, paddingHeight, depth_multiplier, 103d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputOffset, output_multiplier, output_shift, 104d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang output_activation_min, output_activation_max, 105d9c5ba866bb0575cbb894c672e0a800844ccf6f8Miao Wang outputData, convertShapeToDims(outputShape)); 10627e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 10727e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang return true; 10827e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang} 10927e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang 11027e9be3904b034e422ee9b6ab70b35ea994d2b39Miao Wang#undef ANDROID_NN_DEPTHWISE_CONV_PARAMETERS 111eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} // namespace nn 112eb1f88846f147d1d80ee0d688fe4635b89a40ffaMiao Wang} // namespace android 113