ArmNN
 24.02
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< GatherNdQueueDescriptor >
 BaseWorkload (const GatherNdQueueDescriptor &descriptor, const WorkloadInfo &info)
 
virtual const std::string & GetName () const override
 
void ExecuteAsync (ExecutionData &executionData) override
 
void PostAllocationConfigure () override
 
const GatherNdQueueDescriptorGetData () const
 
arm::pipe::ProfilingGuid GetGuid () const final
 
virtual bool SupportsTensorHandleReplacement () const override
 
- Public Member Functions inherited from IWorkload
virtual ~IWorkload ()
 
virtual arm::pipe::ProfilingGuid GetGuid () const =0
 
virtual bool SupportsTensorHandleReplacement () const =0
 
virtual const std::string & GetName () const =0
 
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< GatherNdQueueDescriptor >
GatherNdQueueDescriptor 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 97 of file NeonGatherNdWorkload.cpp.

99  : NeonBaseWorkload<GatherNdQueueDescriptor>(descriptor, info)
100 {
101  m_Data.ValidateInputsOutputs("NeonGatherNdWorkload", 2, 1);
102 
103  TensorInfo paramsInfo = info.m_InputTensorInfos[0];
104  TensorInfo indicesInfo = info.m_InputTensorInfos[1];
105  TensorInfo outputInfo = info.m_OutputTensorInfos[0];
106 
107  arm_compute::ITensor& input = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
108  arm_compute::ITensor& indices = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[1])->GetTensor();
109  arm_compute::ITensor& output = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
110 
111  // Calculate ND, K, W, C.
112  std::map<std::string, unsigned int> keyIndices = CalculateGatherNdKeyIndices(paramsInfo, indicesInfo);
113 
114  /// Calculate flattened indices: m_FlattenedIndices = indices * m_FlattenedCoeff.
115  /// This could be done using MatMul instead of multiplication followed by reduce sum operation,
116  /// but GeMM does not support s32 at the moment.
117 
118  // Prepare the tensor to store the output of the reduce_sum operation
119  armnn::TensorInfo flattenedIndices_Info = indicesInfo;
120  flattenedIndices_Info.SetShape({ keyIndices["W"] });
121  BuildArmComputeTensor(m_FlattenedIndices, flattenedIndices_Info);
122  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_FlattenedIndices);
123 
124  // Reshape indices into { W, ND }
125  indices.info()->set_tensor_shape(BuildArmComputeTensorShape({ keyIndices["W"], keyIndices["ND"] }));
126 
127  // Calculate the m_FlattenedCoeff
128  TensorShape paramsShape = paramsInfo.GetShape();
129  std::vector<int32_t> flattenedCoeff(keyIndices["ND"], 1);
130  for (unsigned int i = 1; i < keyIndices["ND"]; ++i)
131  {
132  flattenedCoeff[i - 1] = static_cast<int32_t>(paramsShape[i]);
133  }
134  for (unsigned int i = keyIndices["ND"] - 1; i > 0; --i)
135  {
136  flattenedCoeff[i - 1] *= flattenedCoeff[i];
137  }
138  armnn::TensorInfo flattenedCoeff_Info = indicesInfo;
139  flattenedCoeff_Info.SetShape({ keyIndices["ND"] });
140  BuildArmComputeTensor(m_FlattenedCoeff, flattenedCoeff_Info);
141  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_FlattenedCoeff);
142  ARMNN_ASSERT_MSG(indicesInfo.GetDataType() == DataType::Signed32,
143  "flattenedCoeff must be same data type as m_FlattenedCoeff");
144  CopyArmComputeITensorData<int32_t>(flattenedCoeff.data(), m_FlattenedCoeff);
145 
146  // Prepare the tensor to store the output of the multiplication
147  armnn::TensorInfo outputMul_Info = indicesInfo;
148  outputMul_Info.SetShape({ keyIndices["W"], keyIndices["ND"] });
149  BuildArmComputeTensor(m_OutputMul, outputMul_Info);
150  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_OutputMul);
151 
152  // Multiply
153  m_MulLayer.configure(&indices,
154  &m_FlattenedCoeff,
155  &m_OutputMul,
156  1.0f,
157  arm_compute::ConvertPolicy::WRAP,
158  arm_compute::RoundingPolicy::TO_ZERO,
159  arm_compute::ActivationLayerInfo());
160 
161  // Reduce Sum
162  const std::vector<unsigned int> armnnReduceAxes(1, 1);
163  arm_compute::Coordinates coords = BuildArmComputeReductionCoordinates(m_OutputMul.info()->num_dimensions(),
164  outputMul_Info.GetNumDimensions(),
165  armnnReduceAxes);
166  m_ReduceSumLayer.configure(&m_OutputMul,
167  &m_FlattenedIndices,
168  static_cast<unsigned int>(coords[0]),
169  arm_compute::ReductionOperation::SUM,
170  false);
171 
172  /// Call Gather with adequate shapes
173  // Reshape params into { K, C }
174  paramsInfo.SetShape({ keyIndices["K"], keyIndices["C"] });
175  input.info()->set_tensor_shape(BuildArmComputeTensorShape(paramsInfo.GetShape()));
176 
177  // Reshape output to have the shape given by gather { W, C }
178  // (the original outputInfo has the shape given by gatherNd)
179  armnn::TensorInfo outputGather_Info = outputInfo;
180  outputGather_Info.SetShape({ keyIndices["W"], keyIndices["C"] });
181  BuildArmComputeTensor(m_OutputGather, outputGather_Info);
182  armcomputetensorutils::InitialiseArmComputeTensorEmpty(m_OutputGather);
183 
184  m_GatherLayer.configure(&input, &m_FlattenedIndices, &m_OutputGather, ComputeAclAxis(0, paramsInfo));
185 
186  // Reshape output to the original output shape
187  m_ReshapeLayer.configure(&m_OutputGather, &output);
188 }

References armnn::CalculateGatherNdKeyIndices(), armnn::info, BaseWorkload< GatherNdQueueDescriptor >::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 190 of file NeonGatherNdWorkload.cpp.

191 {
192  ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID("NeonGatherNdWorkload_Execute");
193  m_MulLayer.run();
194  m_ReduceSumLayer.run();
195  m_GatherLayer.run();
196  m_ReshapeLayer.run();
197 }

References ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID.


The documentation for this class was generated from the following files:
armnn::QueueDescriptor::ValidateInputsOutputs
void ValidateInputsOutputs(const std::string &descName, unsigned int numExpectedIn, unsigned int numExpectedOut) const
Definition: WorkloadData.cpp:446
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::TensorInfo::GetNumDimensions
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:197
ARMNN_ASSERT_MSG
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
armnn::Coordinates
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
Definition: InternalTypes.hpp:15
armnn::CalculateGatherNdKeyIndices
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)
Definition: WorkloadUtils.cpp:312
armnn::BoostLogSeverityMapping::info
@ info
armnn::QueueDescriptor::m_Outputs
std::vector< ITensorHandle * > m_Outputs
Definition: WorkloadData.hpp:27
armnn::DataType::Signed32
@ Signed32
armnn::BaseWorkload< GatherNdQueueDescriptor >::m_Data
GatherNdQueueDescriptor m_Data
Definition: Workload.hpp:89
armnn::TensorInfo::SetShape
void SetShape(const TensorShape &newShape)
Definition: Tensor.hpp:195
ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID
#define ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID(label)
Creates a profiling event that uses GetGuid() and GetName() from the calling class.
Definition: NeonWorkloadUtils.hpp:32
armnn::ComputeAclAxis
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,...
Definition: ArmComputeUtils.hpp:273
armnn::QueueDescriptor::m_Inputs
std::vector< ITensorHandle * > m_Inputs
Definition: WorkloadData.hpp:26