ArmNN
 23.02
ClGatherNdWorkload Class Reference

#include <ClGatherNdWorkload.hpp>

Inheritance diagram for ClGatherNdWorkload:
ClBaseWorkload< GatherNdQueueDescriptor > BaseWorkload< GatherNdQueueDescriptor > IWorkload

Public Member Functions

 ClGatherNdWorkload (const GatherNdQueueDescriptor &descriptor, const WorkloadInfo &info, const arm_compute::CLCompileContext &clCompileContext)
 
virtual void Execute () const override
 
- Public Member Functions inherited from ClBaseWorkload< GatherNdQueueDescriptor >
 ClBaseWorkload (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)
 
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 void RegisterDebugCallback (const DebugCallbackFunction &)
 
virtual armnn::Optional< armnn::MemoryRequirementsGetMemoryRequirements ()
 

Additional Inherited Members

- Protected Member Functions inherited from ClBaseWorkload< GatherNdQueueDescriptor >
virtual void Reconfigure ()
 
- Protected Attributes inherited from BaseWorkload< GatherNdQueueDescriptor >
GatherNdQueueDescriptor m_Data
 
const arm::pipe::ProfilingGuid m_Guid
 

Detailed Description

Definition at line 22 of file ClGatherNdWorkload.hpp.

Constructor & Destructor Documentation

◆ ClGatherNdWorkload()

ClGatherNdWorkload ( const GatherNdQueueDescriptor descriptor,
const WorkloadInfo info,
const arm_compute::CLCompileContext &  clCompileContext 
)

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 99 of file ClGatherNdWorkload.cpp.

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

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 198 of file ClGatherNdWorkload.cpp.

199 {
200  ARMNN_SCOPED_PROFILING_EVENT_CL_GUID("ClGatherNdWorkload_Execute", this->GetGuid());
201  RunClFunction(m_MulLayer, CHECK_LOCATION());
202  RunClFunction(m_ReduceSumLayer, CHECK_LOCATION());
203  RunClFunction(m_GatherLayer, CHECK_LOCATION());
204  RunClFunction(m_ReshapeLayer, CHECK_LOCATION());
205 }

References ARMNN_SCOPED_PROFILING_EVENT_CL_GUID, CHECK_LOCATION, BaseWorkload< GatherNdQueueDescriptor >::GetGuid(), and armnn::RunClFunction().


The documentation for this class was generated from the following files:
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:300
armnn::BaseWorkload< GatherNdQueueDescriptor >::GetGuid
arm::pipe::ProfilingGuid GetGuid() const final
Definition: Workload.hpp:61
armnn::QueueDescriptor::ValidateInputsOutputs
void ValidateInputsOutputs(const std::string &descName, unsigned int numExpectedIn, unsigned int numExpectedOut) const
Definition: WorkloadData.cpp:475
CHECK_LOCATION
#define CHECK_LOCATION()
Definition: Exceptions.hpp:203
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:264
armnn::DataType::Signed32
@ Signed32
armnn::BaseWorkload< GatherNdQueueDescriptor >::m_Data
GatherNdQueueDescriptor m_Data
Definition: Workload.hpp:83
armnn::TensorInfo::GetNumDimensions
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:195
ARMNN_SCOPED_PROFILING_EVENT
#define ARMNN_SCOPED_PROFILING_EVENT(backendId, name)
Definition: Profiling.hpp:220
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::RunClFunction
void RunClFunction(arm_compute::IFunction &function, const CheckLocation &location)
Definition: ClWorkloadUtils.hpp:160
armnn::Compute::Undefined
@ Undefined
ARMNN_ASSERT_MSG
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
armnn::QueueDescriptor::m_Outputs
std::vector< ITensorHandle * > m_Outputs
Definition: WorkloadData.hpp:27
armnn::TensorInfo::SetShape
void SetShape(const TensorShape &newShape)
Definition: Tensor.hpp:193
ARMNN_SCOPED_PROFILING_EVENT_CL_GUID
#define ARMNN_SCOPED_PROFILING_EVENT_CL_GUID(name, guid)
Definition: ClWorkloadUtils.hpp:28
armnn::Coordinates
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
Definition: InternalTypes.hpp:15
armnn::QueueDescriptor::m_Inputs
std::vector< ITensorHandle * > m_Inputs
Definition: WorkloadData.hpp:26
armnn::BoostLogSeverityMapping::info
@ info