1e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang/* 2e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * Copyright (C) 2018 The Android Open Source Project 3e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * 4e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * you may not use this file except in compliance with the License. 6e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * You may obtain a copy of the License at 7e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * 8e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * http://www.apache.org/licenses/LICENSE-2.0 9e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * 10e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * Unless required by applicable law or agreed to in writing, software 11e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * distributed under the License is distributed on an "AS IS" BASIS, 12e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * See the License for the specific language governing permissions and 14e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang * limitations under the License. 15e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang */ 16e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 17e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang// Contains the implementation of the operations. 18e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 19e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang#define LOG_TAG "Operations" 20e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 21e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang#include "Operations.h" 22e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang#include "CpuOperationUtils.h" 23e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 24e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang#include "tensorflow/contrib/lite/kernels/internal/reference/reference_ops.h" 25e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 26e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wangnamespace android { 27e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wangnamespace nn { 28e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 29e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wangbool stridedSliceGeneric(const uint8_t* inputData, const Shape& inputShape, 30b66b5abcef40e88df6ac18ce7890372192102323Miao Wang const int32_t* beginData, const int32_t* endData, 31e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang const int32_t* stridesData, 32b66b5abcef40e88df6ac18ce7890372192102323Miao Wang int32_t beginMask, int32_t endMask, int32_t shrinkAxisMask, 33e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang uint8_t* outputData, const Shape& outputShape) { 34e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang // This Op only supports 1-4D cases and since we use the reference 4D 35e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang // implementation, the 1-3D tensors are mapped to 4D. 36e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang const int kMaxDim = 4; 37e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 38e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang std::vector<int> starts; 39e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang std::vector<int> stops; 40e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang std::vector<int> strides; 41e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 42e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang int32_t numInputDims = static_cast<int32_t>(getNumberOfDimensions(inputShape)); 43e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang for (int32_t idx = numInputDims - 1; idx >= 0; --idx) { 44e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang int32_t dim = static_cast<int32_t>(getSizeOfDimension(inputShape, idx)); 45e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang int32_t stride = stridesData[idx]; 46e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang // stride value has to be non-zero 47e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang NN_OPS_CHECK(stride != 0); 48e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang bool positiveStride = stride > 0; 49e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 50e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang int32_t begin = beginMask & (1 << idx) 51e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang ? positiveStride ? 0 : dim - 1 52e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang : ClampedIndex(beginData[idx], dim, positiveStride); 53e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang int32_t end = endMask & (1 << idx) 54e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang ? positiveStride ? dim : -1 55e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang : ClampedIndex(endData[idx], dim, positiveStride); 56e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 57e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang starts.emplace_back(begin); 58e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang stops.emplace_back(end); 59e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang strides.emplace_back(stride); 60e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang } 61e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 62e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang for (int i = numInputDims; i < kMaxDim; i++) { 63e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang starts.emplace_back(0); 64e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang stops.emplace_back(1); 65e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang strides.emplace_back(1); 66e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang } 67e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 68e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang beginMask = ReverseMaskBits(beginMask, numInputDims); 69e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang endMask = ReverseMaskBits(endMask, numInputDims); 70b66b5abcef40e88df6ac18ce7890372192102323Miao Wang shrinkAxisMask = ReverseMaskBits(shrinkAxisMask, numInputDims); 71e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 72e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang if (inputShape.type == OperandType::TENSOR_FLOAT32) { 73e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang tflite::reference_ops::StridedSlice( 74e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang reinterpret_cast<const float*>(inputData), 75e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang convertShapeToDims(inputShape), 76b66b5abcef40e88df6ac18ce7890372192102323Miao Wang beginMask, endMask, shrinkAxisMask, 77b66b5abcef40e88df6ac18ce7890372192102323Miao Wang starts, stops, strides, 78e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang reinterpret_cast<float*>(outputData), 79e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang convertShapeToDims(outputShape)); 80e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang } else if (inputShape.type == OperandType::TENSOR_QUANT8_ASYMM) { 81e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang tflite::reference_ops::StridedSlice( 82e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang reinterpret_cast<const uint8_t*>(inputData), 83e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang convertShapeToDims(inputShape), 84b66b5abcef40e88df6ac18ce7890372192102323Miao Wang beginMask, endMask, shrinkAxisMask, 85b66b5abcef40e88df6ac18ce7890372192102323Miao Wang starts, stops, strides, 86e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang reinterpret_cast<uint8_t*>(outputData), 87e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang convertShapeToDims(outputShape)); 88e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang } else { 89e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang LOG(ERROR) << "Unsupported data type"; 90e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang return false; 91e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang } 92e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 93e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang return true; 94e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang} 95e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang 96e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang} // namespace nn 97e3ee676c6097e4b2be1232cb4d646a54321a5869Miao Wang} // namespace android 98