blob: 55e6dd05fdf74ef00b51ff147863a2ac76e5d78e [file] [log] [blame]
//
// Copyright © 2021, 2024 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include "Conv3dTestImpl.hpp"
#include <armnnUtils/QuantizeHelper.hpp>
#include <armnnUtils/DataLayoutIndexed.hpp>
#include <armnn/backends/TensorHandle.hpp>
#include <armnnTestUtils/DataLayoutUtils.hpp>
#include <armnnTestUtils/TensorCopyUtils.hpp>
#include <armnnTestUtils/WorkloadTestUtils.hpp>
#include <armnnTestUtils/TensorHelpers.hpp>
using namespace armnnUtils;
//
// Helper templates
//
// Helper template that returns a quantized bias depending on the number of output channels.
template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
std::vector<T> GetBiasData(bool biasEnabled, float qScale, armnn::TensorInfo outputInfo, armnn::DataLayout layout)
{
if(!biasEnabled)
{
return std::vector<T>();
}
else
{
const armnnUtils::DataLayoutIndexed dataLayoutIndexed(layout);
const unsigned int outputChannels = outputInfo.GetShape()[dataLayoutIndexed.GetChannelsIndex()];
switch (outputChannels)
{
case 1:
{
return QuantizedVector<T>({2}, qScale, 0);
}
case 2:
default:
{
return QuantizedVector<T>({0, 2}, qScale, 0);
}
}
}
}
// Modifies a std::vector in-place using a specified bias.
template<typename T, typename B>
void ApplyBiasToData(std::vector<T>& v, const std::vector<B>& bias,
float vScale, int32_t vOffset,
float bScale, int32_t bOffset)
{
CHECK_MESSAGE(((armnn::IsQuantizedType<T>() && vScale != 0.0f) || (!armnn::IsQuantizedType<T>())),
"Invalid type and parameter combination.");
CHECK_MESSAGE(((armnn::IsQuantizedType<B>() && bScale != 0.0f) || (!armnn::IsQuantizedType<B>())),
"Invalid type and parameter combination.");
for (uint32_t i = 0; i < bias.size(); ++i)
{
for (size_t j = i; j < v.size(); j+=bias.size())
{
// Note we need to dequantize and re-quantize the image value and the bias.
float dBias = SelectiveDequantize(bias[i], bScale, bOffset);
T& outRef = v[j];
float dOutput = SelectiveDequantize(outRef, vScale, vOffset);
outRef = SelectiveQuantize<T>(dOutput + dBias, vScale, vOffset);
}
}
}
// Set the quantization scale and offset values for data types.
template<armnn::DataType ArmnnType>
void SetScaleOffset(float& qScale, int32_t& qOffset)
{
switch (ArmnnType)
{
case armnn::DataType::QAsymmU8:
{
qScale = 0.1f;
qOffset = 128;
break;
}
case armnn::DataType::QAsymmS8:
{
qScale = 0.1f;
qOffset = 64;
break;
}
case armnn::DataType::QSymmS16:
{
qScale = 0.1f;
qOffset = 0;
break;
}
case armnn::DataType::BFloat16:
case armnn::DataType::Float16:
case armnn::DataType::Float32:
default:
{
qScale = 1.f;
qOffset = 0;
break;
}
}
}
// Create a vector from 0 to size and quantize (if required).
template <typename T>
std::vector<T> CreateQuantizedData(int32_t size, float qScale, int32_t qOffset)
{
std::vector<float> data;
for (int32_t i = 0; i < size; ++i)
{
data.push_back(static_cast<float>(i));
}
return QuantizedVector<T>(data, qScale, qOffset);
}
// Create a vector from 0 to size divided and then quantized (if required) to create smaller floating point values.
template <typename T>
std::vector<T> CreateSmallQuantizedData(int32_t size, float divisor, float qScale, int32_t qOffset)
{
std::vector<float> data;
for (int32_t i = 0; i < size; ++i)
{
float value = static_cast<float>(i);
data.push_back(value/divisor);
}
return QuantizedVector<T>(data, qScale, qOffset);;
}
//
// Convolution3d implementations
//
template<armnn::DataType ArmnnType,
armnn::DataType ArmnnBType,
typename T = armnn::ResolveType<ArmnnType>,
typename B = armnn::ResolveType<ArmnnBType>>
LayerTestResult<T, 5> SimpleConvolution3dTestImpl(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
const std::vector<T>& input,
const std::vector<T>& kernel,
const std::vector<B>& bias,
const std::vector<T>& outputExpected,
const armnn::TensorShape& inputShape,
const armnn::TensorShape& kernelShape,
const armnn::TensorShape& outputExpectedShape,
const armnn::DataLayout dataLayout,
float qScale,
int32_t qOffset,
uint32_t strideX = 1,
uint32_t strideY = 1,
uint32_t strideZ = 1,
uint32_t dilationX = 1,
uint32_t dilationY = 1,
uint32_t dilationZ = 1,
uint32_t padLeft = 0,
uint32_t padTop = 0,
uint32_t padRight = 0,
uint32_t padBottom = 0,
uint32_t padFront = 0,
uint32_t padBack = 0)
{
unsigned int inputNum = armnn::numeric_cast<unsigned int>(inputShape[0]);
unsigned int inputDepth = armnn::numeric_cast<unsigned int>(inputShape[1]);
unsigned int inputHeight = armnn::numeric_cast<unsigned int>(inputShape[2]);
unsigned int inputWidth = armnn::numeric_cast<unsigned int>(inputShape[3]);
unsigned int inputChannels = armnn::numeric_cast<unsigned int>(inputShape[4]);
// Conv3d weights/kernel layout: [D,H,W,I,O]
unsigned int kernelDepth = armnn::numeric_cast<unsigned int>(kernelShape[0]);
unsigned int kernelHeight = armnn::numeric_cast<unsigned int>(kernelShape[1]);
unsigned int kernelWidth = armnn::numeric_cast<unsigned int>(kernelShape[2]);
unsigned int kernelInChannels = armnn::numeric_cast<unsigned int>(kernelShape[3]);
unsigned int kernelOutChannels = armnn::numeric_cast<unsigned int>(kernelShape[4]);
unsigned int outputNum = armnn::numeric_cast<unsigned int>(outputExpectedShape[0]);
unsigned int outputDepth = armnn::numeric_cast<unsigned int>(outputExpectedShape[1]);
unsigned int outputHeight = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
unsigned int outputWidth = armnn::numeric_cast<unsigned int>(outputExpectedShape[3]);
unsigned int outputChannels = armnn::numeric_cast<unsigned int>(outputExpectedShape[4]);
bool biasEnabled = bias.size() > 0;
// If a bias is used, its size must equal the number of output channels.
CHECK((!biasEnabled || (bias.size() == outputChannels)));
// Creates the tensors.
armnn::TensorInfo inputTensorInfo({inputNum, inputDepth, inputHeight, inputWidth, inputChannels}, ArmnnType);
armnn::TensorInfo outputTensorInfo({outputNum, outputDepth, outputHeight, outputWidth, outputChannels}, ArmnnType);
armnn::TensorInfo kernelDesc({kernelDepth, kernelHeight, kernelWidth, kernelInChannels, kernelOutChannels},
ArmnnType);
armnn::TensorInfo biasDesc({static_cast<unsigned int>(bias.size())}, ArmnnBType);
// Set quantization parameters if the requested type is a quantized type.
if(armnn::IsQuantizedType<T>())
{
inputTensorInfo.SetQuantizationScale(qScale);
inputTensorInfo.SetQuantizationOffset(qOffset);
outputTensorInfo.SetQuantizationScale(qScale);
outputTensorInfo.SetQuantizationOffset(qOffset);
kernelDesc.SetQuantizationScale(qScale);
kernelDesc.SetQuantizationOffset(qOffset);
biasDesc.SetQuantizationScale(qScale*qScale);
biasDesc.SetQuantizationOffset(0);
}
// Construct the input data.
std::vector<T> inputData;
inputData.assign(input.data(), input.data() + inputNum*inputDepth*inputHeight*inputWidth*inputChannels);
// Construct the output data and apply bias if needed.
std::vector<T> outputData;
outputData.assign(outputExpected.data(), outputExpected.data() +
outputNum*outputDepth*outputHeight*outputWidth*outputChannels);
if (biasEnabled)
{
ApplyBiasToData(outputData, bias,
outputTensorInfo.GetQuantizationScale(), outputTensorInfo.GetQuantizationOffset(),
biasDesc.GetQuantizationScale(), biasDesc.GetQuantizationOffset());
}
// Permute input and output if data layout is NCDHW.
if (dataLayout == armnn::DataLayout::NCDHW)
{
PermuteTensorNdhwcToNcdhw(inputTensorInfo, inputData);
PermuteTensorNdhwcToNcdhw(outputTensorInfo, outputData);
}
std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
std::unique_ptr<armnn::ITensorHandle> input0Handle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
std::unique_ptr<armnn::ITensorHandle> input1Handle = tensorHandleFactory.CreateTensorHandle(kernelDesc);
std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
armnn::Convolution3dQueueDescriptor data;
data.m_Parameters.m_StrideX = strideX;
data.m_Parameters.m_StrideY = strideY;
data.m_Parameters.m_StrideZ = strideZ;
data.m_Parameters.m_PadLeft = padLeft;
data.m_Parameters.m_PadRight = padRight;
data.m_Parameters.m_PadTop = padTop;
data.m_Parameters.m_PadBottom = padBottom;
data.m_Parameters.m_PadFront = padFront;
data.m_Parameters.m_PadBack = padBack;
data.m_Parameters.m_DilationX = dilationX;
data.m_Parameters.m_DilationY = dilationY;
data.m_Parameters.m_DilationZ = dilationZ;
data.m_Parameters.m_DataLayout = dataLayout;
data.m_Parameters.m_BiasEnabled = biasEnabled;
armnn::WorkloadInfo info;
AddInputToWorkload(data, info, inputTensorInfo, input0Handle.get());
AddInputToWorkload(data, info, kernelDesc, input1Handle.get());
AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
std::unique_ptr<armnn::ITensorHandle> input2Handle = nullptr;
if (biasEnabled)
{
input2Handle = tensorHandleFactory.CreateTensorHandle(biasDesc);
AddInputToWorkload(data, info, biasDesc, input2Handle.get());
}
std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::Convolution3d,
data,
info);
input0Handle->Allocate();
input1Handle->Allocate();
outputHandle->Allocate();
CopyDataToITensorHandle(input0Handle.get(), inputData.data());
CopyDataToITensorHandle(input1Handle.get(), kernel.data());
if (biasEnabled)
{
input2Handle->Allocate();
CopyDataToITensorHandle(input2Handle.get(), bias.data());
}
ExecuteWorkload(*workload, memoryManager);
CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
return LayerTestResult<T, 5>(actualOutput,
outputData,
outputHandle->GetShape(),
outputTensorInfo.GetShape());
}
template<armnn::DataType ArmnnType,
armnn::DataType ArmnnBType,
typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 5> SimpleConvolution3d3x3x3TestCommon(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
float qScale;
int32_t qOffset;
SetScaleOffset<ArmnnType>(qScale, qOffset);
armnn::TensorInfo inputDesc({ 1, 5, 5, 5, 1 }, ArmnnType);
std::vector<T> input = CreateQuantizedData<T>(125, qScale, qOffset);
armnn::TensorInfo kernelDesc({ 3, 3, 3, 1, 1 }, ArmnnType);
std::vector<T> kernel = QuantizedVector<T>(
{
1, 1, 1,
1, 1, 1,
1, 1, 1,
0, 0, 0,
0, 1, 0,
0, 0, 0,
1, 1, 1,
1, 1, 1,
1, 1, 1,
},
qScale, qOffset);
armnn::TensorInfo outputDesc({ 1, 3, 3, 3, 1 }, ArmnnType);
std::vector<T> outputData = QuantizedVector<T>(
{
589, 608, 627,
684, 703, 722,
779, 798, 817,
1064, 1083, 1102,
1159, 1178, 1197,
1254, 1273, 1292,
1539, 1558, 1577,
1634, 1653, 1672,
1729, 1748, 1767
},
qScale, qOffset);
return SimpleConvolution3dTestImpl<ArmnnType, ArmnnBType>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<ArmnnBType>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset
);
}
template<armnn::DataType ArmnnType,
armnn::DataType ArmnnBType,
typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 5> Convolution3d2x2x2Strides3x5x5TestCommon(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
float qScale;
int32_t qOffset;
SetScaleOffset<ArmnnType>(qScale, qOffset);
armnn::TensorInfo inputDesc({ 1, 3, 10, 10, 1 }, ArmnnType);
std::vector<T> input = CreateQuantizedData<T>(300, qScale, qOffset);
armnn::TensorInfo kernelDesc({ 3, 5, 5, 1, 1 }, ArmnnType);
std::vector<T> kernel = QuantizedVector<T>(
{
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
2, 2, 2, 2, 2,
2, 2, 2, 2, 2,
2, 2, 2, 2, 2,
2, 2, 2, 2, 2,
2, 2, 2, 2, 2,
},
qScale, qOffset);
armnn::TensorInfo outputDesc({ 1, 1, 3, 3, 1 }, ArmnnType);
std::vector<T> outputData = QuantizedVector<T>(
{
11650, 11800, 11950,
13150, 13300, 13450,
14650, 14800, 14950
},
qScale, qOffset);
return SimpleConvolution3dTestImpl<ArmnnType, ArmnnBType>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<ArmnnBType>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset,
2, // strideX
2, // strideY
2 // strideZ
);
}
template<armnn::DataType ArmnnType,
armnn::DataType ArmnnBType,
typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 5> Convolution3d2x2x2Dilation2x2x2TestCommon(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
float qScale;
int32_t qOffset;
SetScaleOffset<ArmnnType>(qScale, qOffset);
armnn::TensorInfo inputDesc({ 1, 5, 5, 5, 2 }, ArmnnType);
std::vector<T> input = CreateQuantizedData<T>(250, qScale, qOffset);
armnn::TensorInfo kernelDesc({ 2, 2, 2, 2, 2 }, ArmnnType);
std::vector<T> kernel = QuantizedVector<T>(
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1,
1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1,
},
qScale, qOffset);
// Since the dilation rate is 3 this will dilate the kernel to be 4x4,
// therefore the output will be 2x2
armnn::TensorInfo outputDesc({ 1, 2, 2, 2, 2 }, ArmnnType);
std::vector<T> outputData = QuantizedVector<T>(
{
-1124, 974,
-1148, 978,
-1244, 994,
-1268, 998,
-1724, 1074,
-1748, 1078,
-1844, 1094,
-1868, 1098
},
qScale, qOffset);
return SimpleConvolution3dTestImpl<ArmnnType, ArmnnBType>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<ArmnnBType>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset,
1, // strideX
1, // strideY
1, // strideZ
3, // dilationX
3, // dilationY
3 // dilationZ
);
}
template<armnn::DataType ArmnnType,
armnn::DataType ArmnnBType,
typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 5> Convolution3dPaddingSame3x3x3TestCommon(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
float qScale;
int32_t qOffset;
SetScaleOffset<ArmnnType>(qScale, qOffset);
armnn::TensorInfo inputDesc({ 1, 5, 5, 5, 1 }, ArmnnType);
std::vector<T> input = CreateQuantizedData<T>(125, qScale, qOffset);
armnn::TensorInfo kernelDesc({ 3, 3, 3, 1, 1 }, ArmnnType);
std::vector<T> kernel = QuantizedVector<T>(
{
1, 1, 1,
1, 1, 1,
1, 1, 1,
0, 0, 0,
0, 0, 0,
0, 0, 0,
1, 1, 1,
1, 1, 1,
1, 1, 1,
},
qScale, qOffset);
armnn::TensorInfo outputDesc({ 1, 5, 5, 5, 1 }, ArmnnType);
std::vector<T> outputData = QuantizedVector<T>(
{
112, 171, 177, 183, 124,
183, 279, 288, 297, 201,
213, 324, 333, 342, 231,
243, 369, 378, 387, 261,
172, 261, 267, 273, 184,
224, 342, 354, 366, 248,
366, 558, 576, 594, 402,
426, 648, 666, 684, 462,
486, 738, 756, 774, 522,
344, 522, 534, 546, 368,
424, 642, 654, 666, 448,
666, 1008, 1026, 1044, 702,
726, 1098, 1116, 1134, 762,
786, 1188, 1206, 1224, 822,
544, 822, 834, 846, 568,
624, 942, 954, 966, 648,
966, 1458, 1476, 1494, 1002,
1026, 1548, 1566, 1584, 1062,
1086, 1638, 1656, 1674, 1122,
744, 1122, 1134, 1146, 768,
312, 471, 477, 483, 324,
483, 729, 738, 747, 501,
513, 774, 783, 792, 531,
543, 819, 828, 837, 561,
372, 561, 567, 573, 384
},
qScale, qOffset);
return SimpleConvolution3dTestImpl<ArmnnType, ArmnnBType>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<ArmnnBType>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset,
1, // strideX
1, // strideY
1, // strideZ
1, // dilationX
1, // dilationY
1, // dilationZ
1, // padLeft
1, // padTop
1, // padRight
1, // padBottom
1, // padFront
1 // padBack
);
}
LayerTestResult<float, 5> Convolution3dStrideDilationPadding3x3x3TestCommonFloat32(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
float qScale = 0.f;
int32_t qOffset = 0;
armnn::TensorInfo inputDesc({ 1, 3, 10, 10, 2 }, armnn::DataType::Float32);
std::vector<float> input = CreateSmallQuantizedData<float>(600, 100.0f, qScale, qOffset);
armnn::TensorInfo kernelDesc({ 3, 3, 3, 2, 2 }, armnn::DataType::Float32);
std::vector<float> kernel = CreateSmallQuantizedData<float>(108, 100.0f, qScale, qOffset);
// Since the dilation rate is 2 this will dilate the kernel to be 5x5: d(K-1)+1 --> 2 x (3-1) + 1 = 5,
// therefore the output will be 1x4x4: (I − K + 2P)/S +1 => trunc((10 - 3 + 2x2 )/3 + 1))
// where, dilation size = d = 2; kernel size = K = 3; input size = I = 10; padding size = P = 2; stride = S = 3
armnn::TensorInfo outputDesc({ 1, 1, 4, 4, 2 }, armnn::DataType::Float32);
std::vector<float> outputData =
{
12.0312f, 12.2268f, 17.7512f, 18.0494f,
18.176f, 18.4814f, 5.6912f, 5.7938f,
19.1664f, 19.5078f, 28.119f, 28.6383f,
28.6914f, 29.2215f, 8.9094f, 9.0873f,
23.1264f, 23.5398f, 33.843f, 34.4703f,
34.4154f, 35.0535f, 10.6734f, 10.8873f,
6.2712f, 6.417f, 9.0718f, 9.2929f,
9.2194f, 9.4441f, 2.7862f, 2.8615f
};
return SimpleConvolution3dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<armnn::DataType::Float32>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset,
3, // strideX
3, // strideY
3, // strideZ
2, // dilationX
2, // dilationY
2, // dilationZ
1, // padLeft
1, // padTop
1, // padRight
1, // padBottom
1, // padFront
1 // padBack
);
}
LayerTestResult<float, 5> Convolution3d2x2x2Stride3x3x3SmallTestCommonFloat32(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
float qScale = 0.f;
int32_t qOffset = 0;
armnn::TensorInfo inputDesc({ 1, 3, 10, 10, 1 }, armnn::DataType::Float32);
std::vector<float> input = CreateSmallQuantizedData<float>(300, 100.0f, qScale, qOffset);
armnn::TensorInfo kernelDesc({ 3, 3, 3, 1, 1 }, armnn::DataType::Float32);
std::vector<float> kernel =
{
0.125977f, 0.150391f, 0.101562f,
0.0585938f, 0.0864258f, 0.043457f,
0.034668f, 0.0322266f, 0.0385742f,
0.125977f, 0.150391f, -0.101562f,
-0.0585938f,-0.0864258f,-0.043457f,
-0.0104630f, 0.0154114f, 0.0013768f,
0.0344238f, 0.035644f, 0.0495605f,
0.0683594f, 0.099121f, -0.0461426f,
-0.0996094f,-0.126953f, -0.043457f,
};
armnn::TensorInfo outputDesc({ 1, 1, 4, 4, 1 }, armnn::DataType::Float32);
std::vector<float> outputData =
{
-0.08156067f, -0.06891209f, -0.05589598f, -0.04310101f,
0.04584253f, 0.05855697f, 0.07129729f, 0.08325434f,
0.17304349f, 0.18521416f, 0.19818866f, 0.21096253f,
0.29965734f, 0.312698f, 0.32547557f, 0.33818722f
};
return SimpleConvolution3dTestImpl<armnn::DataType::Float32, armnn::DataType::Float32>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<armnn::DataType::Float32>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset,
2, // strideX
2, // strideY
2 // strideZ
);
}
LayerTestResult<armnn::Half, 5> Convolution3d2x3x3TestCommonFloat16(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
using namespace half_float::literal;
float qScale = 0.f;
int32_t qOffset = 0;
armnn::TensorInfo inputDesc({ 1, 2, 3, 3, 2 }, armnn::DataType::Float16);
const std::vector<armnn::Half> input =
{
1._h, 2._h, 3._h,
4._h, 5._h, 6._h,
7._h, 8._h, 9._h,
10._h, 11._h, 12._h,
13._h, 14._h, 15._h,
16._h, 17._h, 18._h,
19._h, 20._h, 21._h,
22._h, 23._h, 24._h,
25._h, 26._h, 27._h,
28._h, 29._h, 30._h,
31._h, 32._h, 33._h,
34._h, 35._h, 36._h
};
armnn::TensorInfo kernelDesc({ 2, 2, 2, 2, 2 }, armnn::DataType::Float16);
std::vector<armnn::Half> kernel =
{
-1._h, -1._h, -1._h, -1._h, -1._h, -1._h, -1._h, -1._h,
-1._h, -1._h, -1._h, 1._h, 1._h, 1._h, -1._h, -1._h,
1._h, 1._h, -1._h, 1._h, -1._h, 1._h, -1._h, 1._h,
-1._h, -1._h, -1._h, 1._h, -1._h, 1._h, -1._h, 1._h,
};
armnn::TensorInfo outputDesc({ 1, 1, 2, 2, 2 }, armnn::DataType::Float16);
std::vector<armnn::Half> outputData =
{
-176._h, 128._h,
-200._h, 132._h,
-248._h, 140._h,
-272._h, 144._h
};
return SimpleConvolution3dTestImpl<armnn::DataType::Float16, armnn::DataType::Float16>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<armnn::DataType::Float16>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset
);
}
LayerTestResult<armnn::Half, 5> Convolution3d2x2x2SmallTestCommonFloat16(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
using namespace half_float::literal;
float qScale = 0.f;
int32_t qOffset = 0;
armnn::TensorInfo inputDesc({ 1, 2, 4, 4, 1 }, armnn::DataType::Float16);
const std::vector<armnn::Half> input =
{
0.0367984_h, 0.0380895_h, 0.0420157_h, 0.0675631_h,
0.0938920_h, 0.0476106_h, 0.1035490_h, 0.1260370_h,
0.0461647_h, 0.0883828_h, 0.1159540_h, 0.0498519_h,
0.0104630_h, 0.0154114_h, 0.00137681_h, 0.0344238_h,
0.0356445_h, 0.0495605_h, 0.0683594_h, 0.0991211_h,
0.0461426_h, 0.0996094_h, 0.1269530_h, 0.0393066_h,
0.103516_h, 0.032544_h, 0.124334_h, 0.0564566_h,
0.0123544_h, 0.0461647_h, 0.0883828_h, 0.1159540_h,
};
armnn::TensorInfo kernelDesc({ 2, 2, 2, 1, 1 }, armnn::DataType::Float16);
std::vector<armnn::Half> kernel =
{
-0.126184_h, -0.150468_h,
-0.101412_h, -0.0586369_h,
-0.0435089_h, 0.0347555_h,
0.0323111_h, 0.0385381_h
};
armnn::TensorInfo outputDesc({ 1, 1, 3, 3, 1 }, armnn::DataType::Float16);
std::vector<armnn::Half> outputData =
{
-0.01718917_h, -0.01370182_h, -0.02727737_h,
-0.02282543_h, -0.03144084_h, -0.04468598_h,
-0.02228982_h, -0.02244923_h, -0.02042268_h
};
return SimpleConvolution3dTestImpl<armnn::DataType::Float16, armnn::DataType::Float16>(
workloadFactory,
memoryManager,
tensorHandleFactory,
input,
kernel,
GetBiasData<armnn::DataType::Float16>(biasEnabled, qScale * qScale, outputDesc, dataLayout),
outputData,
inputDesc.GetShape(),
kernelDesc.GetShape(),
outputDesc.GetShape(),
dataLayout,
qScale,
qOffset
);
}
LayerTestResult<float, 5> SimpleConvolution3d3x3x3Float32Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return SimpleConvolution3d3x3x3TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int8_t, 5> SimpleConvolution3d3x3x3Int8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return SimpleConvolution3d3x3x3TestCommon<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<uint8_t, 5> SimpleConvolution3d3x3x3Uint8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return SimpleConvolution3d3x3x3TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int16_t, 5> SimpleConvolution3d3x3x3Int16Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return SimpleConvolution3d3x3x3TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<float, 5> Convolution3d2x2x2Strides3x5x5Float32Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Strides3x5x5TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int8_t, 5> Convolution3d2x2x2Strides3x5x5Int8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Strides3x5x5TestCommon<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<uint8_t, 5> Convolution3d2x2x2Strides3x5x5Uint8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Strides3x5x5TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int16_t, 5> Convolution3d2x2x2Strides3x5x5Int16Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Strides3x5x5TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<float, 5> Convolution3d2x2x2Dilation2x2x2Float32Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Dilation2x2x2TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int8_t, 5> Convolution3d2x2x2Dilation2x2x2Int8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Dilation2x2x2TestCommon<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<uint8_t, 5> Convolution3d2x2x2Dilation2x2x2Uint8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Dilation2x2x2TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int16_t, 5> Convolution3d2x2x2Dilation2x2x2Int16Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Dilation2x2x2TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<float, 5> Convolution3dPaddingSame3x3x3Float32Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3dPaddingSame3x3x3TestCommon<armnn::DataType::Float32, armnn::DataType::Float32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int8_t, 5> Convolution3dPaddingSame3x3x3Int8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3dPaddingSame3x3x3TestCommon<armnn::DataType::QAsymmS8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<uint8_t, 5> Convolution3dPaddingSame3x3x3Uint8Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3dPaddingSame3x3x3TestCommon<armnn::DataType::QAsymmU8, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<int16_t, 5> Convolution3dPaddingSame3x3x3Int16Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3dPaddingSame3x3x3TestCommon<armnn::DataType::QSymmS16, armnn::DataType::Signed32>(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<float, 5> Convolution3dStrideDilationPadding3x3x3Float32Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3dStrideDilationPadding3x3x3TestCommonFloat32(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<float, 5> Convolution3d2x2x2Stride3x3x3SmallFloat32Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2Stride3x3x3SmallTestCommonFloat32(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<armnn::Half, 5> Convolution3d2x3x3Float16Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x3x3TestCommonFloat16(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}
LayerTestResult<armnn::Half, 5> Convolution3d2x2x2SmallFloat16Test(
armnn::IWorkloadFactory& workloadFactory,
const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
const armnn::ITensorHandleFactory& tensorHandleFactory,
bool biasEnabled,
armnn::DataLayout dataLayout)
{
return Convolution3d2x2x2SmallTestCommonFloat16(
workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout);
}