/* * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __NNFW_SUPPORT_NNAPI_OPERATION_UTILS_H__ #define __NNFW_SUPPORT_NNAPI_OPERATION_UTILS_H__ #include #include #include #include #include "model/Operand.h" #include "model/DataType.h" #include using OperandType = neurun::model::DataType; namespace neurun { namespace backend { namespace cpu { namespace kernel { struct Shape { OperandType type; std::vector dimensions; float scale; int32_t offset; }; union DataPtr { uint8_t *u8; int8_t *i8; int32_t *i32; float *f; void *v; }; uint32_t getNumberOfDimensions(const Shape &shape); uint32_t getNumberOfElements(const Shape &shape); uint32_t getSizeOfDimension(const Shape &shape, uint32_t dimensionIdx); inline nnfw::cker::Shape convertToExtendedCkerShape(const Shape &shape) { std::vector raw_shape; raw_shape.resize(4); uint32_t src = 4 - shape.dimensions.size(); for (uint32_t i = 0; i < 4; ++i) { if (i < src) { raw_shape[i] = 1; } else { raw_shape[i] = shape.dimensions[i - src]; } } return nnfw::cker::GetShape(raw_shape); } inline nnfw::cker::Shape convertShapeToCkerShape(const Shape &shape) { std::vector raw_shape; raw_shape.resize(4); for (uint32_t i = 0; i < 4; ++i) { if (i >= shape.dimensions.size()) { raw_shape[i] = 1; } else { raw_shape[i] = shape.dimensions[i]; } } return nnfw::cker::GetShape(raw_shape); } inline int32_t getAxis(uint32_t rank, int32_t axis, ::neurun::model::Layout frontend_layout) { auto ret = axis; if (axis < 0) { ret += rank; } // NCHW -> NHWC if (frontend_layout == ::neurun::model::Layout::NCHW) { int32_t permutation[4] = {0, 3, 1, 2}; ret = permutation[ret]; } return ret; } void QuantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift); void GetQuantizedConvolutionMultiplier(const Shape &inputShape, const Shape &filterShape, const Shape &biasShape, const Shape &outputShape, float *multiplier); void QuantizeMultiplierGreaterThanOne(double double_multiplier, int32_t *quantized_multiplier, int *left_shift); void CalculateActivationRangeFloat(model::Activation activation, float *activation_min, float *activation_max); void CalculateActivationRangeUint8(model::Activation activation, const Shape &outputShape, int32_t *act_min, int32_t *act_max); int32_t CalculateInputRadius(int input_integer_bits, int input_left_shift); Shape getShape(const ::neurun::model::Operand &o, ::neurun::model::Layout frontend_layout); uint32_t sizeOfData(OperandType type, const std::vector &dimensions); } // namespace kernel } // namespace cpu } // namespace backend } // namespace neurun #endif // __NNFW_SUPPORT_NNAPI_OPERATION_UTILS_H__