ArmNN
 25.02
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NeonGatherNdWorkload Class Reference

#include <NeonGatherNdWorkload.hpp>

Inheritance diagram for NeonGatherNdWorkload:
[legend]
Collaboration diagram for NeonGatherNdWorkload:
[legend]

Public Member Functions

 NeonGatherNdWorkload (const GatherNdQueueDescriptor &descriptor, const WorkloadInfo &info)
 
virtual void Execute () const override
 
- Public Member Functions inherited from NeonBaseWorkload< GatherNdQueueDescriptor >
 NeonBaseWorkload (const GatherNdQueueDescriptor &descriptor, const WorkloadInfo &info)
 
void ReplaceInputTensorHandle (ITensorHandle *tensorHandle, unsigned int slot) override
 
void ReplaceOutputTensorHandle (ITensorHandle *tensorHandle, unsigned int slot) override
 
- Public Member Functions inherited from BaseWorkload< QueueDescriptor >
 BaseWorkload (const QueueDescriptor &descriptor, const WorkloadInfo &info)
 
virtual const std::string & GetName () const override
 
void PostAllocationConfigure () override
 
const QueueDescriptorGetData () const
 
arm::pipe::ProfilingGuid GetGuid () const final
 
virtual bool SupportsTensorHandleReplacement () const override
 
- Public Member Functions inherited from IWorkload
virtual ~IWorkload ()
 
virtual void RegisterDebugCallback (const DebugCallbackFunction &)
 
virtual armnn::Optional< armnn::MemoryRequirementsGetMemoryRequirements ()
 

Additional Inherited Members

- Protected Member Functions inherited from NeonBaseWorkload< GatherNdQueueDescriptor >
virtual void Reconfigure ()
 
- Protected Attributes inherited from BaseWorkload< QueueDescriptor >
QueueDescriptor m_Data
 
const arm::pipe::ProfilingGuid m_Guid
 
const std::string m_Name
 

Detailed Description

Definition at line 22 of file NeonGatherNdWorkload.hpp.

Constructor & Destructor Documentation

◆ NeonGatherNdWorkload()

NeonGatherNdWorkload ( const GatherNdQueueDescriptor descriptor,
const WorkloadInfo info 
)

Calculate flattened indices: m_FlattenedIndices = indices * m_FlattenedCoeff. This could be done using MatMul instead of multiplication followed by reduce sum operation, but GeMM does not support s32 at the moment.

Call Gather with adequate shapes

Definition at line 107 of file NeonGatherNdWorkload.cpp.

109  : NeonBaseWorkload<GatherNdQueueDescriptor>(descriptor, info)
110 {
111  m_Data.ValidateInputsOutputs("NeonGatherNdWorkload", 2, 1);
112 
113  TensorInfo paramsInfo = info.m_InputTensorInfos[0];
114  TensorInfo indicesInfo = info.m_InputTensorInfos[1];
115  TensorInfo outputInfo = info.m_OutputTensorInfos[0];
116 
117  arm_compute::ITensor& input = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
118  arm_compute::ITensor& indices = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[1])->GetTensor();
119  arm_compute::ITensor& output = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
120 
121  // Calculate ND, K, W, C.
122  std::map<std::string, unsigned int> keyIndices = CalculateGatherNdKeyIndices(paramsInfo, indicesInfo);
123 
124  /// Calculate flattened indices: m_FlattenedIndices = indices * m_FlattenedCoeff.
125  /// This could be done using MatMul instead of multiplication followed by reduce sum operation,
126  /// but GeMM does not support s32 at the moment.
127 
128  // Prepare the tensor to store the output of the reduce_sum operation
129  armnn::TensorInfo flattenedIndices_Info = indicesInfo;
130  flattenedIndices_Info.SetShape({ keyIndices["W"] });
131  BuildArmComputeTensor(m_FlattenedIndices, flattenedIndices_Info);
132  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_FlattenedIndices);
133 
134  // Reshape indices into { W, ND }
135  armnn::TensorInfo indicesInfoReshape = indicesInfo;
136  indicesInfoReshape.SetShape({ keyIndices["W"], keyIndices["ND"] });
137  BuildArmComputeTensor(m_IndicesReshaped, indicesInfoReshape);
138  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_IndicesReshaped);
139 
140  // Calculate the m_FlattenedCoeff
141  TensorShape paramsShape = paramsInfo.GetShape();
142  std::vector<int32_t> flattenedCoeff(keyIndices["ND"], 1);
143  for (unsigned int i = 1; i < keyIndices["ND"]; ++i)
144  {
145  flattenedCoeff[i - 1] = static_cast<int32_t>(paramsShape[i]);
146  }
147  for (unsigned int i = keyIndices["ND"] - 1; i > 0; --i)
148  {
149  flattenedCoeff[i - 1] *= flattenedCoeff[i];
150  }
151  armnn::TensorInfo flattenedCoeff_Info = indicesInfo;
152  flattenedCoeff_Info.SetShape({ keyIndices["ND"] });
153  BuildArmComputeTensor(m_FlattenedCoeff, flattenedCoeff_Info);
154  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_FlattenedCoeff);
155  CopyArmComputeITensorData<int32_t>(flattenedCoeff.data(), m_FlattenedCoeff);
156 
157  // Prepare the tensor to store the output of the multiplication
158  armnn::TensorInfo outputMul_Info = indicesInfo;
159  outputMul_Info.SetShape({ keyIndices["W"], keyIndices["ND"] });
160  BuildArmComputeTensor(m_OutputMul, outputMul_Info);
161  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_OutputMul);
162 
163  // Reshape indices to the mul layer input shape
164  m_ReshapeIndicesLayer.configure(&indices, &m_IndicesReshaped);
165 
166  // Multiply
167  m_MulLayer.configure(&m_IndicesReshaped,
168  &m_FlattenedCoeff,
169  &m_OutputMul,
170  1.0f,
171  arm_compute::ConvertPolicy::WRAP,
172  arm_compute::RoundingPolicy::TO_ZERO,
173  arm_compute::ActivationLayerInfo());
174 
175  // Reduce Sum
176  const std::vector<unsigned int> armnnReduceAxes(1, 1);
177  arm_compute::Coordinates coords = BuildArmComputeReductionCoordinates(m_OutputMul.info()->num_dimensions(),
178  outputMul_Info.GetNumDimensions(),
179  armnnReduceAxes);
180  m_ReduceSumLayer.configure(&m_OutputMul,
181  &m_FlattenedIndices,
182  static_cast<unsigned int>(coords[0]),
183  arm_compute::ReductionOperation::SUM,
184  false);
185 
186  /// Call Gather with adequate shapes
187  // Reshape params into { K, C }
188  armnn::TensorInfo paramsInfoReshape = paramsInfo;
189  paramsInfoReshape.SetShape({ keyIndices["K"], keyIndices["C"] });
190  BuildArmComputeTensor(m_InputGather, paramsInfoReshape);
191  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_InputGather);
192 
193  // Reshape input to the gather params input shape
194  m_ReshapeInputLayer.configure(&input, &m_InputGather);
195 
196  // Reshape output to have the shape given by gather { W, C }
197  // (the original outputInfo has the shape given by gatherNd)
198  armnn::TensorInfo outputGather_Info = outputInfo;
199  outputGather_Info.SetShape({ keyIndices["W"], keyIndices["C"] });
200  BuildArmComputeTensor(m_OutputGather, outputGather_Info);
201  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_OutputGather);
202 
203  m_GatherLayer.configure(&m_InputGather,
204  &m_FlattenedIndices,
205  &m_OutputGather,
206  ComputeAclAxis(0, paramsInfoReshape));
207 
208  // Reshape output to the original output shape
209  m_ReshapeOutputLayer.configure(&m_OutputGather, &output);
210 }
QueueDescriptor m_Data
Definition: Workload.hpp:74
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:197
void SetShape(const TensorShape &newShape)
Definition: Tensor.hpp:195
int ComputeAclAxis(const int &armnnAxis, const armnn::TensorInfo &tensor)
Function to convert ArmNN axis (left to right) to ACL axis (right to left) ranging from [-rank,...
std::map< std::string, unsigned int > CalculateGatherNdKeyIndices(TensorInfo inputInfo0, TensorInfo inputInfo1)
Calculates the key index values needed for GatherNd: N, ND, K, W, C (N is always 1)
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
std::vector< ITensorHandle * > m_Inputs
std::vector< ITensorHandle * > m_Outputs
void ValidateInputsOutputs(const std::string &descName, unsigned int numExpectedIn, unsigned int numExpectedOut) const

References armnn::CalculateGatherNdKeyIndices(), armnn::info, BaseWorkload< QueueDescriptor >::m_Data, QueueDescriptor::m_Inputs, QueueDescriptor::m_Outputs, TensorInfo::SetShape(), and QueueDescriptor::ValidateInputsOutputs().

Member Function Documentation

◆ Execute()

void Execute ( ) const
overridevirtual

Implements IWorkload.

Definition at line 212 of file NeonGatherNdWorkload.cpp.

213 {
214  ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID("NeonGatherNdWorkload_Execute");
215  m_ReshapeInputLayer.run();
216  m_ReshapeIndicesLayer.run();
217  m_MulLayer.run();
218  m_ReduceSumLayer.run();
219  m_GatherLayer.run();
220  m_ReshapeOutputLayer.run();
221 }
#define ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID(label)
Creates a profiling event that uses GetGuid() and GetName() from the calling class.

References ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID.


The documentation for this class was generated from the following files: