From 81ec994a3ebc8ad02c4a622846cf64b70e1182bd Mon Sep 17 00:00:00 2001 From: Matthew Sloyan Date: Tue, 12 Oct 2021 10:26:30 +0100 Subject: IVGCVSW-6166 Add Support for Conv3d to TFLite Delegate * Conv3d is only correctly supported for external delegates from TF v2.6, as there was a breaking bug in v2.5. Signed-off-by: Matthew Sloyan Change-Id: Ib7941307f4c7b0d3dbb7deaa5a90aceb63c1162f --- delegate/src/test/Convolution3dTest.cpp | 273 ++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 delegate/src/test/Convolution3dTest.cpp (limited to 'delegate/src/test/Convolution3dTest.cpp') diff --git a/delegate/src/test/Convolution3dTest.cpp b/delegate/src/test/Convolution3dTest.cpp new file mode 100644 index 0000000000..6caa7ea18f --- /dev/null +++ b/delegate/src/test/Convolution3dTest.cpp @@ -0,0 +1,273 @@ +// +// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ConvolutionTestHelper.hpp" + +#include + +#include +#include +#include +#include +#include + +#include + +namespace armnnDelegate +{ + +// Conv3d is currently only supports Float32 inputs, filter, bias and outputs in TFLite. +// Conv3d is only correctly supported for external delegates from TF Lite v2.6, as there was a breaking bug in v2.5. +#if defined(ARMNN_POST_TFLITE_2_5) + +// Create a vector from 0 to size divided to create smaller floating point values. +template +std::vector CreateFloatData(int32_t size, float divisor) +{ + std::vector data; + for (int32_t i = 0; i < size; ++i) + { + float value = static_cast(i); + data.push_back(value/divisor); + } + return data; +} + +void Conv3DWithBiasesSimpleWithPaddingFp32Test(std::vector& backends) +{ + // Set input data + std::vector inputShape { 1, 2, 2, 2, 1 }; + std::vector filterShape { 2, 2, 2, 1, 1 }; + std::vector biasShape { 1 }; + std::vector outputShape { 1, 2, 2, 2, 1 }; + + static std::vector inputValues = + { + 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f + }; + + std::vector filterValues = + { + 2.f,1.f, 1.f,0.f, 0.f,1.f, 1.f,1.f + }; + + std::vector biasValues = { 5.f }; + + std::vector expectedOutputValues = + { + 33.f, 21.f, 23.f, 13.f, 28.f, 25.f, 27.f, 21.f + }; + + Convolution3dTest(tflite::BuiltinOperator_CONV_3D, + ::tflite::TensorType_FLOAT32, + { 1, 1, 1 }, // strideX, strideY, strideZ + { 1, 1, 1 }, // dilationX, dilationY, dilationZ + tflite::Padding_SAME, + tflite::ActivationFunctionType_NONE, + backends, + inputShape, + filterShape, + outputShape, + inputValues, + filterValues, + expectedOutputValues, + biasShape, + biasValues); +} + +void Conv3DWithBiasesStridesFp32Test(std::vector& backends) +{ + std::vector inputShape { 1, 3, 10, 10, 1 }; + std::vector filterShape { 3, 5, 5, 1, 1 }; + std::vector biasShape { 1 }; + std::vector outputShape { 1, 1, 3, 3, 1 }; + + std::vector inputValues = CreateFloatData(300, 1.0f); + + std::vector filterValues = + { + 1.f, 1.f, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 1.f, 1.f, + + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + + 2.f, 2.f, 2.f, 2.f, 2.f, + 2.f, 2.f, 2.f, 2.f, 2.f, + 2.f, 2.f, 2.f, 2.f, 2.f, + 2.f, 2.f, 2.f, 2.f, 2.f, + 2.f, 2.f, 2.f, 2.f, 2.f + }; + + std::vector biasValues = { 10.f }; + + std::vector expectedOutputValues = + { + 11660.f, 11810.f, 11960.f, + + 13160.f, 13310.f, 13460.f, + + 14660.f, 14810.f, 14960.f + }; + + Convolution3dTest(tflite::BuiltinOperator_CONV_3D, + ::tflite::TensorType_FLOAT32, + { 2, 2, 2 }, // strideX, strideY, strideZ + { 1, 1, 1 }, // dilationX, dilationY, dilationZ + tflite::Padding_VALID, + tflite::ActivationFunctionType_NONE, + backends, + inputShape, + filterShape, + outputShape, + inputValues, + filterValues, + expectedOutputValues, + biasShape, + biasValues); +} + + +void Conv3DWithBiasesDilationFp32Test(std::vector& backends) +{ + std::vector inputShape { 1, 5, 5, 5, 2 }; + std::vector filterShape { 2, 2, 2, 2, 2 }; + std::vector biasShape { 2 }; + std::vector outputShape { 1, 2, 2, 2, 2 }; + + std::vector inputValues = CreateFloatData(250, 1.0f); + + std::vector filterValues = + { + -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, -1.f, + 1.f, 1.f, -1.f, 1.f, -1.f, 1.f, -1.f, 1.f, -1.f, -1.f, -1.f, 1.f, -1.f, 1.f, -1.f, 1.f, + }; + + std::vector biasValues = { 0.f, 2.f }; + + // Since the dilation rate is 3 this will dilate the kernel to be 4x4, + // therefore the output will be 2x2 + std::vector expectedOutputValues = + { + -1124.f, 976.f, + -1148.f, 980.f, + + -1244.f, 996.f, + -1268.f, 1000.f, + + -1724.f, 1076.f, + -1748.f, 1080.f, + + -1844.f, 1096.f, + -1868.f, 1100.f + }; + + Convolution3dTest(tflite::BuiltinOperator_CONV_3D, + ::tflite::TensorType_FLOAT32, + { 1, 1, 1 }, // strideX, strideY, strideZ + { 3, 3, 3 }, // dilationX, dilationY, dilationZ + tflite::Padding_VALID, + tflite::ActivationFunctionType_NONE, + backends, + inputShape, + filterShape, + outputShape, + inputValues, + filterValues, + expectedOutputValues, + biasShape, + biasValues); +} + +void Conv3DFp32SmallTest(std::vector& backends) +{ + std::vector inputShape { 1, 3, 10, 10, 1 }; + std::vector filterShape { 3, 3, 3, 1, 1 }; + std::vector biasShape { 1 }; + std::vector outputShape { 1, 1, 4, 4, 1 }; + + std::vector inputValues = CreateFloatData(300, 100.0f); + + std::vector filterValues = + { + 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, + }; + + std::vector biasValues = { 0 }; + + std::vector expectedOutputValues = + { + -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 + }; + + Convolution3dTest(tflite::BuiltinOperator_CONV_3D, + ::tflite::TensorType_FLOAT32, + { 2, 2, 2 }, // strideX, strideY, strideZ + { 1, 1, 1 }, // dilationX, dilationY, dilationZ + tflite::Padding_VALID, + tflite::ActivationFunctionType_NONE, + backends, + inputShape, + filterShape, + outputShape, + inputValues, + filterValues, + expectedOutputValues, + biasShape, + biasValues); +} + +TEST_SUITE("Convolution3dTest_CpuRefTests") +{ + +TEST_CASE ("Conv3DWithBiasesSimpleWithPadding_Fp32_CpuRef_Test") +{ + std::vector backends = {armnn::Compute::CpuRef}; + Conv3DWithBiasesSimpleWithPaddingFp32Test(backends); +} + +TEST_CASE ("Conv3DWithBiasesStrides_Fp32_CpuRef_Test") +{ + std::vector backends = {armnn::Compute::CpuRef}; + Conv3DWithBiasesStridesFp32Test(backends); +} + +TEST_CASE ("Conv3DWithBiasesDilation_Fp32_CpuRef_Test") +{ + std::vector backends = {armnn::Compute::CpuRef}; + Conv3DWithBiasesDilationFp32Test(backends); +} + +TEST_CASE ("Conv3DFp32Small_Fp32_CpuRef_Test") +{ + std::vector backends = {armnn::Compute::CpuRef}; + Conv3DFp32SmallTest(backends); +} + + +} //End of TEST_SUITE("Convolution3dTest_CpuRefTests") + +#endif + +} // namespace armnnDelegate \ No newline at end of file -- cgit v1.2.1