// // Copyright © 2021 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "Conv3dTestImpl.hpp" #include #include #include #include #include #include #include using namespace armnnUtils; // // Helper templates // // Helper template that returns a quantized bias depending on the number of output channels. template> std::vector GetBiasData(bool biasEnabled, float qScale, armnn::TensorInfo outputInfo, armnn::DataLayout layout) { if(!biasEnabled) { return std::vector(); } else { const armnnUtils::DataLayoutIndexed dataLayoutIndexed(layout); const unsigned int outputChannels = outputInfo.GetShape()[dataLayoutIndexed.GetChannelsIndex()]; switch (outputChannels) { case 1: { return QuantizedVector({2}, qScale, 0); } case 2: default: { return QuantizedVector({0, 2}, qScale, 0); } } } } // Modifies a std::vector in-place using a specified bias. template void ApplyBiasToData(std::vector& v, const std::vector& bias, float vScale, int32_t vOffset, float bScale, int32_t bOffset) { ARMNN_ASSERT_MSG((armnn::IsQuantizedType() && vScale != 0.0f) || (!armnn::IsQuantizedType()), "Invalid type and parameter combination."); ARMNN_ASSERT_MSG((armnn::IsQuantizedType() && bScale != 0.0f) || (!armnn::IsQuantizedType()), "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(dOutput + dBias, vScale, vOffset); } } } // Set the quantization scale and offset values for data types. template 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 std::vector CreateQuantizedData(int32_t size, float qScale, int32_t qOffset) { std::vector data; for (int32_t i = 0; i < size; ++i) { data.push_back(static_cast(i)); } return QuantizedVector(data, qScale, qOffset); } // Create a vector from 0 to size divided and then quantized (if required) to create smaller floating point values. template std::vector CreateSmallQuantizedData(int32_t size, float divisor, float qScale, int32_t qOffset) { std::vector data; for (int32_t i = 0; i < size; ++i) { float value = static_cast(i); data.push_back(value/divisor); } return QuantizedVector(data, qScale, qOffset);; } // // Convolution3d implementations // template, typename B = armnn::ResolveType> LayerTestResult SimpleConvolution3dTestImpl( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, const std::vector& input, const std::vector& kernel, const std::vector& bias, const std::vector& 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(inputShape[0]); unsigned int inputDepth = armnn::numeric_cast(inputShape[1]); unsigned int inputHeight = armnn::numeric_cast(inputShape[2]); unsigned int inputWidth = armnn::numeric_cast(inputShape[3]); unsigned int inputChannels = armnn::numeric_cast(inputShape[4]); // Conv3d weights/kernel layout: [D,H,W,I,O] unsigned int kernelDepth = armnn::numeric_cast(kernelShape[0]); unsigned int kernelHeight = armnn::numeric_cast(kernelShape[1]); unsigned int kernelWidth = armnn::numeric_cast(kernelShape[2]); unsigned int kernelInChannels = armnn::numeric_cast(kernelShape[3]); unsigned int kernelOutChannels = armnn::numeric_cast(kernelShape[4]); unsigned int outputNum = armnn::numeric_cast(outputExpectedShape[0]); unsigned int outputDepth = armnn::numeric_cast(outputExpectedShape[1]); unsigned int outputHeight = armnn::numeric_cast(outputExpectedShape[2]); unsigned int outputWidth = armnn::numeric_cast(outputExpectedShape[3]); unsigned int outputChannels = armnn::numeric_cast(outputExpectedShape[4]); bool biasEnabled = bias.size() > 0; // If a bias is used, its size must equal the number of output channels. ARMNN_ASSERT(!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(bias.size())}, ArmnnBType); // Set quantization parameters if the requested type is a quantized type. if(armnn::IsQuantizedType()) { 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 inputData; inputData.assign(input.data(), input.data() + inputNum*inputDepth*inputHeight*inputWidth*inputChannels); // Construct the output data and apply bias if needed. std::vector 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 actualOutput(outputTensorInfo.GetNumElements()); std::unique_ptr input0Handle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo); std::unique_ptr input1Handle = tensorHandleFactory.CreateTensorHandle(kernelDesc); std::unique_ptr 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 input2Handle = nullptr; if (biasEnabled) { input2Handle = tensorHandleFactory.CreateTensorHandle(biasDesc); AddInputToWorkload(data, info, biasDesc, input2Handle.get()); } std::unique_ptr 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(actualOutput, outputData, outputHandle->GetShape(), outputTensorInfo.GetShape()); } template> LayerTestResult SimpleConvolution3d3x3x3TestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { float qScale; int32_t qOffset; SetScaleOffset(qScale, qOffset); armnn::TensorInfo inputDesc({ 1, 5, 5, 5, 1 }, ArmnnType); std::vector input = CreateQuantizedData(125, qScale, qOffset); armnn::TensorInfo kernelDesc({ 3, 3, 3, 1, 1 }, ArmnnType); std::vector kernel = QuantizedVector( { 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 outputData = QuantizedVector( { 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( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(biasEnabled, qScale * qScale, outputDesc, dataLayout), outputData, inputDesc.GetShape(), kernelDesc.GetShape(), outputDesc.GetShape(), dataLayout, qScale, qOffset ); } template> LayerTestResult Convolution3d2x2x2Strides3x5x5TestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { float qScale; int32_t qOffset; SetScaleOffset(qScale, qOffset); armnn::TensorInfo inputDesc({ 1, 3, 10, 10, 1 }, ArmnnType); std::vector input = CreateQuantizedData(300, qScale, qOffset); armnn::TensorInfo kernelDesc({ 3, 5, 5, 1, 1 }, ArmnnType); std::vector kernel = QuantizedVector( { 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 outputData = QuantizedVector( { 11650, 11800, 11950, 13150, 13300, 13450, 14650, 14800, 14950 }, qScale, qOffset); return SimpleConvolution3dTestImpl( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(biasEnabled, qScale * qScale, outputDesc, dataLayout), outputData, inputDesc.GetShape(), kernelDesc.GetShape(), outputDesc.GetShape(), dataLayout, qScale, qOffset, 2, // strideX 2, // strideY 2 // strideZ ); } template> LayerTestResult Convolution3d2x2x2Dilation2x2x2TestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { float qScale; int32_t qOffset; SetScaleOffset(qScale, qOffset); armnn::TensorInfo inputDesc({ 1, 5, 5, 5, 2 }, ArmnnType); std::vector input = CreateQuantizedData(250, qScale, qOffset); armnn::TensorInfo kernelDesc({ 2, 2, 2, 2, 2 }, ArmnnType); std::vector kernel = QuantizedVector( { -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 outputData = QuantizedVector( { -1124, 974, -1148, 978, -1244, 994, -1268, 998, -1724, 1074, -1748, 1078, -1844, 1094, -1868, 1098 }, qScale, qOffset); return SimpleConvolution3dTestImpl( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(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> LayerTestResult Convolution3dPaddingSame3x3x3TestCommon( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { float qScale; int32_t qOffset; SetScaleOffset(qScale, qOffset); armnn::TensorInfo inputDesc({ 1, 5, 5, 5, 1 }, ArmnnType); std::vector input = CreateQuantizedData(125, qScale, qOffset); armnn::TensorInfo kernelDesc({ 3, 3, 3, 1, 1 }, ArmnnType); std::vector kernel = QuantizedVector( { 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 outputData = QuantizedVector( { 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( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(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 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 input = CreateSmallQuantizedData(600, 100.0f, qScale, qOffset); armnn::TensorInfo kernelDesc({ 3, 3, 3, 2, 2 }, armnn::DataType::Float32); std::vector kernel = CreateSmallQuantizedData(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 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( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(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 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 input = CreateSmallQuantizedData(300, 100.0f, qScale, qOffset); armnn::TensorInfo kernelDesc({ 3, 3, 3, 1, 1 }, armnn::DataType::Float32); std::vector 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 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( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(biasEnabled, qScale * qScale, outputDesc, dataLayout), outputData, inputDesc.GetShape(), kernelDesc.GetShape(), outputDesc.GetShape(), dataLayout, qScale, qOffset, 2, // strideX 2, // strideY 2 // strideZ ); } LayerTestResult 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 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 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 outputData = { -176._h, 128._h, -200._h, 132._h, -248._h, 140._h, -272._h, 144._h }; return SimpleConvolution3dTestImpl( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(biasEnabled, qScale * qScale, outputDesc, dataLayout), outputData, inputDesc.GetShape(), kernelDesc.GetShape(), outputDesc.GetShape(), dataLayout, qScale, qOffset ); } LayerTestResult 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 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 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 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( workloadFactory, memoryManager, tensorHandleFactory, input, kernel, GetBiasData(biasEnabled, qScale * qScale, outputDesc, dataLayout), outputData, inputDesc.GetShape(), kernelDesc.GetShape(), outputDesc.GetShape(), dataLayout, qScale, qOffset ); } LayerTestResult SimpleConvolution3d3x3x3Float32Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return SimpleConvolution3d3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult SimpleConvolution3d3x3x3Int8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return SimpleConvolution3d3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult SimpleConvolution3d3x3x3Uint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return SimpleConvolution3d3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult SimpleConvolution3d3x3x3Int16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return SimpleConvolution3d3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Strides3x5x5Float32Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Strides3x5x5TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Strides3x5x5Int8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Strides3x5x5TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Strides3x5x5Uint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Strides3x5x5TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Strides3x5x5Int16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Strides3x5x5TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Dilation2x2x2Float32Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Dilation2x2x2TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Dilation2x2x2Int8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Dilation2x2x2TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Dilation2x2x2Uint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Dilation2x2x2TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3d2x2x2Dilation2x2x2Int16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3d2x2x2Dilation2x2x2TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3dPaddingSame3x3x3Float32Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3dPaddingSame3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3dPaddingSame3x3x3Int8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3dPaddingSame3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3dPaddingSame3x3x3Uint8Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3dPaddingSame3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult Convolution3dPaddingSame3x3x3Int16Test( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, bool biasEnabled, armnn::DataLayout dataLayout) { return Convolution3dPaddingSame3x3x3TestCommon( workloadFactory, memoryManager, tensorHandleFactory, biasEnabled, dataLayout); } LayerTestResult 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 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 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 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); }