ArmNN
 24.02
ClSpaceToBatchNdWorkload.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
7 
9 
10 #include <cl/ClTensorHandle.hpp>
11 
12 namespace armnn
13 {
14 using namespace armcomputetensorutils;
15 
17  const TensorInfo& output,
18  const SpaceToBatchNdDescriptor& descriptor)
19 {
20  arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
21  arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
22 
23  arm_compute::Status statusSpaceToBatch = arm_compute::Status(arm_compute::ErrorCode::OK);
24  arm_compute::Status statusReshapeInput = arm_compute::Status(arm_compute::ErrorCode::OK);
25  arm_compute::Status statusReshapeOutput = arm_compute::Status(arm_compute::ErrorCode::OK);
26 
27  arm_compute::TensorInfo aclReshapeInputInfo = aclInputInfo;
28  arm_compute::TensorInfo aclReshapeOutputInfo = aclOutputInfo;
29 
30  // When a spacial dimension is missing (rank=3) set W to 1
31  const unsigned int rank = input.GetNumDimensions();
32  if (rank == 3)
33  {
34  const arm_compute::TensorShape inputShape = aclInputInfo.tensor_shape();
35  const arm_compute::TensorShape outputShape = aclOutputInfo.tensor_shape();
36 
37  if (descriptor.m_DataLayout == armnn::DataLayout::NHWC)
38  {
39  // In ACL dimensions are right to left: C, W, H, N
40  aclInputInfo.set_tensor_shape({inputShape.x(), 1, inputShape.y(), inputShape.z()});
41  aclOutputInfo.set_tensor_shape({outputShape.x(), 1, outputShape.y(), outputShape.z()});
42  }
43  else if (descriptor.m_DataLayout == armnn::DataLayout::NCHW)
44  {
45  // In ACL dimensions are right to left: W, H, C, N
46  aclInputInfo.set_tensor_shape({1, inputShape.x(), inputShape.y(), inputShape.z()});
47  aclOutputInfo.set_tensor_shape({1, outputShape.x(), outputShape.y(), outputShape.z()});
48  }
49  else
50  {
51  throw InvalidArgumentException("Unsupported or unknown DataLayout", CHECK_LOCATION());
52  }
53 
54  statusReshapeInput = arm_compute::CLReshapeLayer::validate(&aclInputInfo, &aclReshapeInputInfo);
55  statusReshapeOutput = arm_compute::CLReshapeLayer::validate(&aclReshapeOutputInfo, &aclOutputInfo);
56  }
57 
58  // ArmNN blockShape is [H, W] ACl asks for W, H
59  int32_t blockHeight = armnn::numeric_cast<int32_t>(descriptor.m_BlockShape[0]);
60  int32_t blockWidth = (rank == 3) ? 1 : armnn::numeric_cast<int32_t>(descriptor.m_BlockShape[1]);
61 
62  unsigned int padLeft = (rank == 3) ? 0 : descriptor.m_PadList[1].first;
63  unsigned int padRight = (rank == 3) ? 0 : descriptor.m_PadList[1].second;
64  arm_compute::Size2D paddingLeftTop = BuildArmComputeSize2D(padLeft,
65  descriptor.m_PadList[0].first);
66  arm_compute::Size2D paddingRightBottom = BuildArmComputeSize2D(padRight,
67  descriptor.m_PadList[0].second);
68 
69  const arm_compute::Status aclStatus = arm_compute::CLSpaceToBatchLayer::validate(&aclInputInfo,
70  blockWidth,
71  blockHeight,
72  paddingLeftTop,
73  paddingRightBottom,
74  &aclOutputInfo);
75 
76  if (statusReshapeInput.error_code() == arm_compute::ErrorCode::OK &&
77  statusReshapeOutput.error_code() == arm_compute::ErrorCode::OK &&
78  statusSpaceToBatch.error_code() == arm_compute::ErrorCode::OK)
79  {
80  return arm_compute::Status(arm_compute::ErrorCode::OK,
81  "All SpaceToBatch layers validate status OK.");
82  }
83  else
84  {
85  return arm_compute::Status(arm_compute::ErrorCode::RUNTIME_ERROR,
86  "SpaceToBatch layer validate status failed."
87  + statusSpaceToBatch.error_description()
88  + statusReshapeInput.error_description()
89  + statusReshapeOutput.error_description());
90  }
91 }
92 
94  const WorkloadInfo& info,
95  const arm_compute::CLCompileContext& clCompileContext)
97 {
98  // Report Profiling Details
99  ARMNN_REPORT_PROFILING_WORKLOAD_DESC("ClSpaceToBatchNdWorkload_Construct",
100  descriptor.m_Parameters,
101  info,
102  this->GetGuid());
103 
104  m_Data.ValidateInputsOutputs("ClSpaceToBatchNdWorkload", 1, 1);
105 
106  arm_compute::ICLTensor& input = PolymorphicPointerDowncast<IClTensorHandle>(m_Data.m_Inputs[0])->GetTensor();
107  arm_compute::ICLTensor& output = PolymorphicPointerDowncast<IClTensorHandle>(m_Data.m_Outputs[0])->GetTensor();
108 
109  arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
110  input.info()->set_data_layout(aclDataLayout);
111  output.info()->set_data_layout(aclDataLayout);
112 
113  arm_compute::TensorInfo aclReshapeInputInfo = BuildArmComputeTensorInfo(info.m_InputTensorInfos[0],
115  arm_compute::TensorInfo aclReshapeOutputInfo = BuildArmComputeTensorInfo(info.m_OutputTensorInfos[0],
117 
118  const unsigned int rank = info.m_InputTensorInfos[0].GetNumDimensions();
119  if (rank == 3)
120  {
121  const arm_compute::TensorShape inputShape = input.info()->tensor_shape();
122  const arm_compute::TensorShape outputShape = output.info()->tensor_shape();
123 
124  // When a spacial dimension is missing set W to 1
126  {
127  // In ACL dimensions are right to left: C, W, H, N
128  aclReshapeInputInfo.set_tensor_shape({inputShape.x(), 1, inputShape.y(), inputShape.z()});
129  aclReshapeOutputInfo.set_tensor_shape({outputShape.x(), 1, outputShape.y(), outputShape.z()});
130  }
132  {
133  // In ACL dimensions are right to left: W, H, C, N
134  aclReshapeInputInfo.set_tensor_shape({1, inputShape.x(), inputShape.y(), inputShape.z()});
135  aclReshapeOutputInfo.set_tensor_shape({1, outputShape.x(), outputShape.y(), outputShape.z()});
136  }
137  else
138  {
139  throw InvalidArgumentException("Unsupported or unknown DataLayout", CHECK_LOCATION());
140  }
141 
142  m_ReshapeInputTensor.allocator()->init(aclReshapeInputInfo);
143  m_ReshapeOutputTensor.allocator()->init(aclReshapeOutputInfo);
144 
145  InitialiseArmComputeTensorEmpty(m_ReshapeInputTensor);
146  InitialiseArmComputeTensorEmpty(m_ReshapeOutputTensor);
147 
148  m_LayerReshapeInput.reset(new arm_compute::CLReshapeLayer());
149  m_LayerReshapeOutput.reset(new arm_compute::CLReshapeLayer());
150 
151  m_LayerReshapeInput->configure(clCompileContext, &input, &m_ReshapeInputTensor);
152  m_LayerReshapeOutput->configure(clCompileContext, &m_ReshapeOutputTensor, &output);
153  }
154 
155  // ArmNN blockShape is [H, W] ACl asks for W, H
156  int32_t blockHeight = armnn::numeric_cast<int32_t>(m_Data.m_Parameters.m_BlockShape[0]);
157  int32_t blockWidth = (rank == 3) ? 1: armnn::numeric_cast<int32_t>(descriptor.m_Parameters.m_BlockShape[1]);
158 
159  unsigned int padLeft = (rank == 3) ? 0 : descriptor.m_Parameters.m_PadList[1].first;
160  unsigned int padRight = (rank == 3) ? 0 : descriptor.m_Parameters.m_PadList[1].second;
161  arm_compute::Size2D paddingLeftTop = BuildArmComputeSize2D(padLeft,
162  descriptor.m_Parameters.m_PadList[0].first);
163  arm_compute::Size2D paddingRightBottom = BuildArmComputeSize2D(padRight,
164  descriptor.m_Parameters.m_PadList[0].second);
165 
166  {
167  ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID("ClSpaceToBatchNdWorkload_configure");
168  m_Layer.configure(clCompileContext,
169  rank == 3 ? &m_ReshapeInputTensor : &input,
170  blockWidth,
171  blockHeight,
172  paddingLeftTop,
173  paddingRightBottom,
174  rank == 3 ? &m_ReshapeOutputTensor : &output);
175  }
176 }
177 
179 {
180  ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID("ClSpaceToBatchNdWorkload_Execute");
181  if (m_LayerReshapeInput)
182  {
183  m_LayerReshapeInput->run();
184  }
185  RunClFunction(m_Layer, CHECK_LOCATION());
186  if (m_LayerReshapeOutput)
187  {
188  m_LayerReshapeOutput->run();
189  }
190 }
191 
192 } //namespace armnn
armnn::DataLayout
DataLayout
Definition: Types.hpp:62
armnn::SpaceToBatchNdDescriptor::m_DataLayout
DataLayout m_DataLayout
The data layout to be used (NCHW, NHWC).
Definition: Descriptors.hpp:1071
armnn::DataLayout::NHWC
@ NHWC
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
CHECK_LOCATION
#define CHECK_LOCATION()
Definition: Exceptions.hpp:203
armnn::ClBaseWorkload
Definition: ClBaseWorkload.hpp:13
armnn::SpaceToBatchNdDescriptor::m_BlockShape
std::vector< unsigned int > m_BlockShape
Block shape value.
Definition: Descriptors.hpp:1066
armnn::SpaceToBatchNdDescriptor::m_PadList
std::vector< std::pair< unsigned int, unsigned int > > m_PadList
Specifies the padding values for the input dimension: heightPad{top, bottom} widthPad{left,...
Definition: Descriptors.hpp:1069
armnn::ClSpaceToBatchNdWorkload::ClSpaceToBatchNdWorkload
ClSpaceToBatchNdWorkload(const SpaceToBatchNdQueueDescriptor &descriptor, const WorkloadInfo &info, const arm_compute::CLCompileContext &clCompileContext)
Definition: ClSpaceToBatchNdWorkload.cpp:93
armnn::QueueDescriptorWithParameters::m_Parameters
LayerDescriptor m_Parameters
Definition: WorkloadData.hpp:66
ClSpaceToBatchNdWorkload.hpp
ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID
#define ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID(label)
Creates a profiling event that uses GetGuid() and GetName() from the calling class.
Definition: ClWorkloadUtils.hpp:36
armnn::WorkloadInfo
Contains information about TensorInfos of a layer.
Definition: WorkloadInfo.hpp:16
PolymorphicDowncast.hpp
armnn::InvalidArgumentException
Definition: Exceptions.hpp:80
armnn::SpaceToBatchNdDescriptor
A SpaceToBatchNdDescriptor for the SpaceToBatchNdLayer.
Definition: Descriptors.hpp:1043
armnn::BoostLogSeverityMapping::info
@ info
armnn::QueueDescriptor::m_Outputs
std::vector< ITensorHandle * > m_Outputs
Definition: WorkloadData.hpp:27
ARMNN_REPORT_PROFILING_WORKLOAD_DESC
#define ARMNN_REPORT_PROFILING_WORKLOAD_DESC(name, desc, infos, guid)
Definition: Profiling.hpp:227
armnn::ClSpaceToBatchNdWorkloadValidate
arm_compute::Status ClSpaceToBatchNdWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const SpaceToBatchNdDescriptor &descriptor)
Definition: ClSpaceToBatchNdWorkload.cpp:16
armnn::Status
Status
Definition: Types.hpp:42
ClTensorHandle.hpp
armnn::BaseWorkload< SpaceToBatchNdQueueDescriptor >::m_Data
SpaceToBatchNdQueueDescriptor m_Data
Definition: Workload.hpp:89
armnn::RunClFunction
void RunClFunction(arm_compute::IFunction &function, const CheckLocation &location)
Definition: ClWorkloadUtils.hpp:168
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::ClSpaceToBatchNdWorkload::Execute
virtual void Execute() const override
Definition: ClSpaceToBatchNdWorkload.cpp:178
armnn::SpaceToBatchNdQueueDescriptor
Definition: WorkloadData.hpp:385
armnn::QueueDescriptor::m_Inputs
std::vector< ITensorHandle * > m_Inputs
Definition: WorkloadData.hpp:26
armnn::DataLayout::NCHW
@ NCHW