12 #include <fmt/format.h>
16 namespace armcomputetensorutils
24 return arm_compute::DataType::BFLOAT16;
26 return arm_compute::DataType::U8;
28 return arm_compute::DataType::F16;
30 return arm_compute::DataType::F32;
32 return arm_compute::DataType::QASYMM8_SIGNED;
34 return arm_compute::DataType::QASYMM8;
36 return arm_compute::DataType::QSYMM16;
38 return arm_compute::DataType::S64;
41 return multiScales ? arm_compute::DataType::QSYMM8_PER_CHANNEL : arm_compute::DataType::QSYMM8;
44 return arm_compute::DataType::S32;
47 return arm_compute::DataType::UNKNOWN;
55 case arm_compute::DataType::BFLOAT16:
57 case arm_compute::DataType::U8:
59 case arm_compute::DataType::F16:
61 case arm_compute::DataType::F32:
63 case arm_compute::DataType::QASYMM8_SIGNED:
65 case arm_compute::DataType::QASYMM8:
67 case arm_compute::DataType::QSYMM16:
69 case arm_compute::DataType::S64:
71 case arm_compute::DataType::QSYMM8_PER_CHANNEL:
73 case arm_compute::DataType::QSYMM8:
75 case arm_compute::DataType::S32:
84 unsigned int originalInputRank,
85 const std::vector<unsigned int>& armnnAxes)
89 if (armnnAxes.empty())
97 outAclCoords.set_num_dimensions(inputDimensions);
98 std::generate(outAclCoords.begin(), outAclCoords.end(), [d = inputDimensions - 1] ()
mutable { return d--; });
116 outAclCoords.set_num_dimensions(armnnAxes.size());
117 std::transform(armnnAxes.begin(), armnnAxes.end(),
118 outAclCoords.begin(),
119 [originalInputRank](
unsigned int i){ return originalInputRank - i - 1; });
125 arm_compute::TensorShape BuildArmComputeTensorShape(
const armnn::TensorShape& tensorShape)
127 arm_compute::TensorShape shape;
141 if (shape.num_dimensions() == 0)
143 shape.set_num_dimensions(1);
149 std::vector<unsigned int> ReduceDimsForACL(
const armnn::TensorShape tensorShape,
unsigned int dimensions)
151 std::vector<unsigned int> newShape;
153 unsigned int dimsToSkip = 0;
159 unsigned int dimsSkipped = 0;
160 bool insertRemainder =
false;
164 if (tensorShape[i] == 1 && dimsSkipped < dimsToSkip && !insertRemainder)
169 newShape.insert(newShape.begin(), tensorShape[i]);
171 insertRemainder =
true;
176 arm_compute::TensorShape BuildArmComputeTensorShape(
const armnn::TensorShape& tensorShape,
unsigned int dimensions)
178 arm_compute::TensorShape shape;
179 std::vector<unsigned int> strippedShape = ReduceDimsForACL(tensorShape, dimensions);
181 for (
unsigned int i = 0; i < strippedShape.size(); i++)
183 shape.set(i, strippedShape[i],
false);
187 if (shape.num_dimensions() == 0)
189 shape.set_num_dimensions(1);
200 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo)
203 const arm_compute::TensorShape aclTensorShape = BuildArmComputeTensorShape(tensorInfo.
GetShape());
206 const arm_compute::QuantizationInfo aclQuantizationInfo = multiScales ?
208 arm_compute::QuantizationInfo(tensorInfo.GetQuantizationScale(), tensorInfo.GetQuantizationOffset());
210 return arm_compute::TensorInfo(aclTensorShape, 1, aclDataType, aclQuantizationInfo);
213 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
216 arm_compute::TensorInfo aclTensorInfo = BuildArmComputeTensorInfo(tensorInfo);
217 aclTensorInfo.set_data_layout(ConvertDataLayout(dataLayout));
219 return aclTensorInfo;
222 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
unsigned int dimensions)
225 const arm_compute::TensorShape aclTensorShape = BuildArmComputeTensorShape(tensorInfo.
GetShape(), dimensions);
228 const arm_compute::QuantizationInfo aclQuantizationInfo = multiScales ?
230 arm_compute::QuantizationInfo(tensorInfo.GetQuantizationScale(), tensorInfo.GetQuantizationOffset());
232 return arm_compute::TensorInfo(aclTensorShape, 1, aclDataType, aclQuantizationInfo);
234 arm_compute::TensorInfo BuildArmComputeTensorInfo(
const armnn::TensorInfo& tensorInfo,
237 arm_compute::TensorInfo aclTensorInfo = BuildArmComputeTensorInfo(tensorInfo, dimensions);
238 aclTensorInfo.set_data_layout(ConvertDataLayout(dataLayout));
240 return aclTensorInfo;
256 default:
throw InvalidArgumentException(
"Unknown armnn::DataLayout: [" +
257 std::to_string(
static_cast<int>(dataLayout)) +
"]");
261 arm_compute::PoolingLayerInfo BuildArmComputePoolingLayerInfo(
const Pooling2dDescriptor& descriptor,
262 bool fpMixedPrecision)
269 bool isGlobalPooling = (descriptor.m_StrideX==0 && descriptor.m_StrideY==0);
273 return arm_compute::PoolingLayerInfo(poolingType, dataLayout);
277 descriptor.m_OutputShapeRounding);
278 const arm_compute::PadStrideInfo padStrideInfo(descriptor.m_StrideX,
279 descriptor.m_StrideY,
280 descriptor.m_PadLeft,
281 descriptor.m_PadRight,
283 descriptor.m_PadBottom,
288 const arm_compute::Size2D poolSize(descriptor.m_PoolWidth, descriptor.m_PoolHeight);
290 return arm_compute::PoolingLayerInfo(poolingType, poolSize, dataLayout, padStrideInfo, excludePadding,
294 arm_compute::Pooling3dLayerInfo BuildArmComputePooling3dLayerInfo(
const Pooling3dDescriptor& descriptor,
295 bool fpMixedPrecision)
299 bool isGlobalPooling = (descriptor.m_StrideX==0 && descriptor.m_StrideY==0 && descriptor.m_StrideZ==0);
303 return arm_compute::Pooling3dLayerInfo(poolingType);
306 const arm_compute::Size3D poolSize(descriptor.m_PoolWidth, descriptor.m_PoolHeight, descriptor.m_PoolDepth);
308 const arm_compute::Size3D stride(descriptor.m_StrideX,
309 descriptor.m_StrideY,
310 descriptor.m_StrideZ);
312 const arm_compute::Padding3D padding(descriptor.m_PadLeft,
313 descriptor.m_PadRight,
315 descriptor.m_PadBottom,
316 descriptor.m_PadFront,
317 descriptor.m_PadBack);
322 descriptor.m_OutputShapeRounding);
324 return arm_compute::Pooling3dLayerInfo(poolingType,
333 arm_compute::NormalizationLayerInfo BuildArmComputeNormalizationLayerInfo(
const NormalizationDescriptor& descriptor)
335 const arm_compute::NormType normType =
337 return arm_compute::NormalizationLayerInfo(normType,
338 descriptor.m_NormSize,
347 arm_compute::PermutationVector aclPerm;
349 unsigned int start = 0;
350 while ((start < perm.
GetSize()) && (start == perm[start]))
355 for (
unsigned int i = start; i < perm.
GetSize(); ++i)
357 aclPerm.set(i - start, perm[i] - start);
386 arm_compute::PermutationVector aclPerm;
390 std::vector<unsigned int> reversedPerm;
391 reversedPerm.reserve(rank);
392 for (
unsigned int i = rank; i > 0; --i)
394 reversedPerm.push_back(perm[i-1]);
398 for (
unsigned int i = 0; i < rank; ++i)
400 auto aclAxis = rank - 1 - reversedPerm[i];
401 aclPerm.set(i, aclAxis);
406 arm_compute::Size2D BuildArmComputeSize2D(
const unsigned int width,
const unsigned int height)
408 return arm_compute::Size2D(width, height);
411 arm_compute::PixelValue GetPixelValue(
const arm_compute::ITensorInfo* tensorInfo,
float value)
413 switch (tensorInfo->data_type())
415 case arm_compute::DataType::F16:
417 arm_compute::PixelValue pixelValue = arm_compute::PixelValue(
static_cast<Half>(value));
418 if (isinf(pixelValue.get<
Half>())) {
419 throw InvalidArgumentException(
"Under/Overflow converting float value [" + std::to_string(value) +
420 "] to fp16: [" + std::to_string(pixelValue.get<
Half>()) +
"]");
424 case arm_compute::DataType::F32:
425 return arm_compute::PixelValue(value);
426 case arm_compute::DataType::QASYMM8:
427 return arm_compute::PixelValue(
static_cast<uint8_t
>(value));
428 case arm_compute::DataType::QSYMM16:
429 return arm_compute::PixelValue(
static_cast<int16_t
>(value));
430 case arm_compute::DataType::QSYMM8:
431 case arm_compute::DataType::QASYMM8_SIGNED:
432 case arm_compute::DataType::QSYMM8_PER_CHANNEL:
433 return arm_compute::PixelValue(
static_cast<int8_t
>(value));
434 case arm_compute::DataType::S32:
435 return arm_compute::PixelValue(
static_cast<int32_t
>(value));
437 throw InvalidArgumentException(
"Unsupported DataType: [" +
438 std::to_string(
static_cast<int>(tensorInfo->data_type())) +
"]");
443 const arm_compute::TensorShape& weightsShape,
444 const arm_compute::TensorShape& inputShape)
446 unsigned int depthMultiplier;
449 depthMultiplier =
static_cast<uint32_t
>(weightsShape[0]) /
static_cast<uint32_t
>(inputShape[0]);
453 depthMultiplier =
static_cast<uint32_t
>(weightsShape[2]) /
static_cast<uint32_t
>(inputShape[2]);
457 throw InvalidArgumentException(fmt::format(
"Unknown data layout for tensor conversion: {}",
460 return depthMultiplier;