ArmNN
 24.08
Concatenate.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017, 2024 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "Concatenate.hpp"
7 #include "RefWorkloadUtils.hpp"
8 #include "Decoders.hpp"
9 #include "Encoders.hpp"
10 
11 namespace armnn
12 {
13 
15  std::vector<ITensorHandle*> inputs,
16  std::vector<ITensorHandle*> outputs)
17 {
18  const TensorInfo& outputInfo0 = GetTensorInfo(outputs[0]);
19 
20  std::unique_ptr<Encoder<float>> encoderPtr = MakeEncoder<float>(outputInfo0, outputs[0]->Map());
21  Encoder<float>& encoder = *encoderPtr;
22 
23  for (unsigned int index = 0 ; index < outputInfo0.GetNumElements(); ++index)
24  {
25  unsigned int indices[MaxNumOfTensorDimensions] = { 0 };
26 
27  unsigned int indexRemainder = index;
28  unsigned int dimensionStride = outputInfo0.GetNumElements();
29 
30  for (unsigned int i = 0; i < outputInfo0.GetNumDimensions(); i++)
31  {
32  dimensionStride /= outputInfo0.GetShape()[i];
33  indices[i] = indexRemainder / dimensionStride; // Use integer division to round down.
34  indexRemainder -= indices[i] * dimensionStride;
35  }
36 
37  for (unsigned int viewIdx = 0; viewIdx < data.m_ViewOrigins.size(); ++viewIdx)
38  {
39  ConcatQueueDescriptor::ViewOrigin const& view = data.m_ViewOrigins[viewIdx];
40 
41  //Split view extents are defined by the size of (the corresponding) input tensor.
42  const TensorInfo& inputInfo = GetTensorInfo(inputs[viewIdx]);
44  inputInfo.GetNumDimensions() == outputInfo0.GetNumDimensions(),
45  "The number of output dimensions does not match the number of input dimensions.");
46 
47  // Check all dimensions to see if this element is inside the given input view.
48  bool insideView = true;
49  for (unsigned int i = 0; i < inputInfo.GetNumDimensions(); i++)
50  {
51  if (indices[i] < view.m_Origin[i])
52  {
53  insideView = false;
54  }
55  if (indices[i] >= view.m_Origin[i] + inputInfo.GetShape()[i])
56  {
57  insideView = false;
58  }
59  }
60 
61  if (insideView)
62  {
63  std::unique_ptr<Decoder<float>> decoderPtr =
64  MakeDecoder<float>(inputInfo,inputs[viewIdx]->Map());
65  Decoder<float>& decoder = *decoderPtr;
66  unsigned int inIndex = 0;
67  unsigned int dimensionStride = 1;
68 
69  for (unsigned int i = inputInfo.GetNumDimensions(); i-- > 0;)
70  {
71  inIndex += dimensionStride * (indices[i] - view.m_Origin[i]);
72  dimensionStride *= inputInfo.GetShape()[i];
73  }
74  decoder += inIndex;
75  encoder.Set(decoder.Get());
76 
77  //What should we do if input views overlap on the output tensor?
78  //We could error, take the average, or shm else...
79  //For now just stop after finding first view (input) that matches.
80  break;
81  }
82  }
83  ++encoder;
84  }
85 }
86 
87 } //namespace armnn
armnn::Decoder< float >
armnn::TensorInfo::GetNumElements
unsigned int GetNumElements() const
Definition: Tensor.hpp:198
armnn::ConcatQueueDescriptor
Definition: WorkloadData.hpp:130
armnn::Encoder::Set
virtual void Set(IType right)=0
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::TensorInfo::GetNumDimensions
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:197
armnn::MaxNumOfTensorDimensions
constexpr unsigned int MaxNumOfTensorDimensions
Definition: Types.hpp:31
armnn::Concatenate
void Concatenate(const ConcatQueueDescriptor &data, std::vector< ITensorHandle * > inputs, std::vector< ITensorHandle * > outputs)
Definition: Concatenate.cpp:14
armnn::Encoder< float >
armnn::ConcatQueueDescriptor::ViewOrigin
Definition: WorkloadData.hpp:132
armnn::ConcatQueueDescriptor::ViewOrigin::m_Origin
std::vector< unsigned int > m_Origin
Definition: WorkloadData.hpp:138
Concatenate.hpp
armnn::GetTensorInfo
const TensorInfo & GetTensorInfo(const ITensorHandle *tensorHandle)
float32 helpers
Definition: RefWorkloadUtils.hpp:33
armnn::Decoder::Get
virtual IType Get() const =0
RefWorkloadUtils.hpp
armnn::TensorInfo::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
armnn::ConcatQueueDescriptor::m_ViewOrigins
std::vector< ViewOrigin > m_ViewOrigins
Definition: WorkloadData.hpp:143
Decoders.hpp
armnn::LayerType::Map
@ Map
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
Encoders.hpp
ARMNN_THROW_INVALIDARG_MSG_IF_FALSE
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
Definition: Exceptions.hpp:210