12 #include <arm_compute/core/ITensor.h>
13 #include <arm_compute/core/TensorInfo.h>
14 #include <arm_compute/core/Types.h>
15 #include <arm_compute/function_info/ScatterInfo.h>
23 namespace armcomputetensorutils
34 unsigned int originalInputRank,
35 const std::vector<unsigned int>& armnnAxes);
38 arm_compute::TensorShape BuildArmComputeTensorShape(
const armnn::TensorShape& tensorShape);
42 arm_compute::TensorShape BuildArmComputeTensorShape(
const armnn::TensorShape& tensorShape,
unsigned int dimensions);
46 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo);
51 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
unsigned int dimensions);
56 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
58 unsigned int dimensions);
63 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
69 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
79 arm_compute::PoolingLayerInfo BuildArmComputePoolingLayerInfo(
const Pooling2dDescriptor& descriptor,
80 bool fpMixedPrecision =
false);
85 arm_compute::Pooling3dLayerInfo BuildArmComputePooling3dLayerInfo(
const Pooling3dDescriptor& descriptor,
86 bool fpMixedPrecision =
false);
89 arm_compute::NormalizationLayerInfo BuildArmComputeNormalizationLayerInfo(
const NormalizationDescriptor& desc);
102 arm_compute::Size2D BuildArmComputeSize2D(
const unsigned int width,
const unsigned int height);
105 arm_compute::PixelValue GetPixelValue(
const arm_compute::ITensorInfo* tensorInfo,
float value);
109 const arm_compute::TensorShape& weightsShape,
110 const arm_compute::TensorShape& inputShape);
113 arm_compute::ScatterInfo BuildArmComputeScatterInfo(
const ScatterNdDescriptor& descriptor);
116 template <
typename Descriptor>
117 arm_compute::PadStrideInfo BuildArmComputePadStrideInfo(
const Descriptor& descriptor)
119 return arm_compute::PadStrideInfo(descriptor.m_StrideX,
120 descriptor.m_StrideY,
121 descriptor.m_PadLeft,
122 descriptor.m_PadRight,
124 descriptor.m_PadBottom,
125 arm_compute::DimensionRoundingType::FLOOR);
129 template <
typename Descriptor>
130 arm_compute::Padding2D BuildArmComputePaddingInfo(
const Descriptor &descriptor)
132 return arm_compute::Padding2D(descriptor.m_PadLeft,
133 descriptor.m_PadRight,
135 descriptor.m_PadBottom);
139 template <
typename Descriptor>
140 arm_compute::CropInfo BuildArmComputeCropInfo(
const Descriptor& descriptor,
const unsigned int rank = 4)
144 return arm_compute::CropInfo(0, 0,
145 descriptor.m_Crops[0].first, descriptor.m_Crops[0].second);
149 return arm_compute::CropInfo(descriptor.m_Crops[1].first, descriptor.m_Crops[1].second,
150 descriptor.m_Crops[0].first, descriptor.m_Crops[0].second);
154 throw InvalidArgumentException(
"Tensor rank must be either 3 or 4",
CHECK_LOCATION());
159 template <
typename Tensor>
162 tensor.allocator()->init(BuildArmComputeTensorInfo(tensorInfo));
166 template <
typename Tensor>
169 tensor.allocator()->init(BuildArmComputeTensorInfo(tensorInfo, dataLayout));
172 template <
typename Tensor>
173 void InitialiseArmComputeTensorEmpty(Tensor& tensor)
175 tensor.allocator()->allocate();
179 template <
typename Tensor>
180 void FreeTensorIfUnused(std::unique_ptr<Tensor>& tensor)
182 if (tensor && !tensor->is_used())
184 tensor.reset(
nullptr);
189 inline size_t GetTensorOffset(
const arm_compute::ITensorInfo& info,
192 uint32_t channelIndex,
197 coords.set(4,
static_cast<int>(depthIndex));
198 coords.set(3,
static_cast<int>(batchIndex));
199 coords.set(2,
static_cast<int>(channelIndex));
200 coords.set(1,
static_cast<int>(y));
201 coords.set(0,
static_cast<int>(x));
202 return armnn::numeric_cast<size_t>(
info.offset_element_in_bytes(coords));
206 inline size_t GetLinearBufferOffset(
const arm_compute::ITensorInfo& info,
209 uint32_t channelIndex,
213 const arm_compute::TensorShape& shape =
info.tensor_shape();
214 uint32_t width =
static_cast<uint32_t
>(shape[0]);
215 uint32_t height =
static_cast<uint32_t
>(shape[1]);
216 uint32_t numChannels =
static_cast<uint32_t
>(shape[2]);
217 uint32_t numBatches =
static_cast<uint32_t
>(shape[3]);
218 return (((depthIndex * numBatches + batchIndex) * numChannels + channelIndex) * height + y) * width + x;
221 template <
typename T>
222 void CopyArmComputeITensorData(
const arm_compute::ITensor& srcTensor, T* dstData)
227 const arm_compute::ITensorInfo&
info = *srcTensor.info();
228 const arm_compute::TensorShape& shape =
info.tensor_shape();
229 const uint8_t*
const bufferPtr = srcTensor.buffer();
230 uint32_t width =
static_cast<uint32_t
>(shape[0]);
231 uint32_t height =
static_cast<uint32_t
>(shape[1]);
232 uint32_t numChannels =
static_cast<uint32_t
>(shape[2]);
233 uint32_t numBatches =
static_cast<uint32_t
>(shape[3]);
234 uint32_t depth =
static_cast<uint32_t
>(shape[4]);
236 for (
unsigned int depthIndex = 0; depthIndex < depth; ++depthIndex)
238 for (
unsigned int batchIndex = 0; batchIndex < numBatches; ++batchIndex)
240 for (
unsigned int channelIndex = 0; channelIndex < numChannels; ++channelIndex)
242 for (
unsigned int y = 0; y < height; ++y)
247 dstData + GetLinearBufferOffset(info, depthIndex, batchIndex, channelIndex, y, 0),
248 bufferPtr + GetTensorOffset(info, depthIndex, batchIndex, channelIndex, y, 0),
257 template <
typename T>
258 void CopyArmComputeITensorData(
const T* srcData, arm_compute::ITensor& dstTensor)
263 const arm_compute::ITensorInfo&
info = *dstTensor.info();
264 const arm_compute::TensorShape& shape =
info.tensor_shape();
265 uint8_t*
const bufferPtr = dstTensor.buffer();
266 uint32_t width =
static_cast<uint32_t
>(shape[0]);
267 uint32_t height =
static_cast<uint32_t
>(shape[1]);
268 uint32_t numChannels =
static_cast<uint32_t
>(shape[2]);
269 uint32_t numBatches =
static_cast<uint32_t
>(shape[3]);
270 uint32_t depth =
static_cast<uint32_t
>(shape[4]);
272 for (
unsigned int depthIndex = 0; depthIndex < depth; ++depthIndex)
274 for (
unsigned int batchIndex = 0; batchIndex < numBatches; ++batchIndex)
276 for (
unsigned int channelIndex = 0; channelIndex < numChannels; ++channelIndex)
278 for (
unsigned int y = 0; y < height; ++y)
283 bufferPtr + GetTensorOffset(info, depthIndex, batchIndex, channelIndex, y, 0),
284 srcData + GetLinearBufferOffset(info, depthIndex, batchIndex, channelIndex, y, 0),
299 template<
typename ArmComputeType,
typename T>
300 TensorShape
GetTensorShape(
const ArmComputeType& shapelike, T initial)
303 for (
unsigned int i=0; i < shapelike.num_dimensions(); ++i)
305 s[(shapelike.num_dimensions()-1)-i] = armnn::numeric_cast<unsigned int>(shapelike[i]);
307 return TensorShape(armnn::numeric_cast<unsigned int>(shapelike.num_dimensions()), s.data());
311 inline TensorShape GetStrides(
const arm_compute::Strides& strides)
317 inline TensorShape GetShape(
const arm_compute::TensorShape& shape)