ArmNN
 25.11
Loading...
Searching...
No Matches
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 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 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 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}
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)

References armnn::CalculateGatherNdKeyIndices(), armnn::ComputeAclAxis(), TensorInfo::GetNumDimensions(), TensorInfo::GetShape(), armnn::info, BaseWorkload< GatherNdQueueDescriptor >::m_Data, NeonBaseWorkload< GatherNdQueueDescriptor >::NeonBaseWorkload(), armnn::PolymorphicDowncast(), and TensorInfo::SetShape().

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: