1 // 2 // Copyright © 2017 Arm Ltd. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 #include "RefWorkloadUtils.hpp" 7 #include <backendsCommon/WorkloadData.hpp> 8 #include <armnn/Tensor.hpp> 9 #include <armnn/utility/Assert.hpp> 10 #include "Splitter.hpp" 11 12 #include <cmath> 13 #include <limits> 14 15 #include "Decoders.hpp" 16 #include "Encoders.hpp" 17 18 namespace armnn 19 { 20 Split(const SplitterQueueDescriptor & data)21void Split(const SplitterQueueDescriptor& data) 22 { 23 const TensorInfo& inputInfo = GetTensorInfo(data.m_Inputs[0]); 24 25 std::unique_ptr<Decoder<float>> decoderPtr = 26 MakeDecoder<float>(inputInfo, data.m_Inputs[0]->Map()); 27 Decoder<float>& decoder = *decoderPtr; 28 29 for (unsigned int index = 0; index < inputInfo.GetNumElements(); ++index) 30 { 31 unsigned int indices[MaxNumOfTensorDimensions] = { 0 }; 32 33 unsigned int indexRemainder = index; 34 unsigned int dimensionStride = inputInfo.GetNumElements(); 35 36 for (unsigned int i = 0; i<inputInfo.GetNumDimensions(); i++) 37 { 38 dimensionStride /= inputInfo.GetShape()[i]; 39 indices[i] = indexRemainder / dimensionStride; // Use integer division to round down. 40 indexRemainder -= indices[i] * dimensionStride; 41 } 42 43 for (unsigned int viewIdx = 0; viewIdx < data.m_ViewOrigins.size(); ++viewIdx) 44 { 45 SplitterQueueDescriptor::ViewOrigin const& view = data.m_ViewOrigins[viewIdx]; 46 47 //Split view extents are defined by the size of (the corresponding) input tensor. 48 const TensorInfo& outputInfo = GetTensorInfo(data.m_Outputs[viewIdx]); 49 ARMNN_ASSERT(outputInfo.GetNumDimensions() == inputInfo.GetNumDimensions()); 50 51 // Check all dimensions to see if this element is inside the given input view. 52 bool insideView = true; 53 for (unsigned int i = 0; i<outputInfo.GetNumDimensions(); i++) 54 { 55 if (indices[i] < view.m_Origin[i]) 56 { 57 insideView = false; 58 } 59 if (indices[i] >= view.m_Origin[i] + outputInfo.GetShape()[i]) 60 { 61 insideView = false; 62 } 63 } 64 65 if (insideView) 66 { 67 std::unique_ptr<Encoder<float>> encoderPtr = 68 MakeEncoder<float>(outputInfo, data.m_Outputs[viewIdx]->Map()); 69 Encoder<float>& encoder = *encoderPtr; 70 71 unsigned int outIndex = 0; 72 unsigned int dimensionStride = 1; 73 float inputValue = 0.f; 74 75 for (unsigned int i = outputInfo.GetNumDimensions(); i-- > 0;) 76 { 77 outIndex += dimensionStride * (indices[i] - view.m_Origin[i]); 78 dimensionStride *= outputInfo.GetShape()[i]; 79 } 80 81 decoder += index; 82 inputValue = decoder.Get(); 83 decoder -= index; 84 85 encoder += outIndex; 86 encoder.Set(inputValue); 87 break; 88 } 89 } 90 } 91 } 92 93 }