From a52bca23d225144e92f521341718a70489d5c217 Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Thu, 1 Feb 2024 17:36:48 +0000 Subject: IVGCVSW-7623: GpuFsa Op: Add Pool2d operator * Add Pool2d EndToEnd tests to all backends * Add utility functions for the attributes in a separate file * Remove some unnecessary includes Signed-off-by: Teresa Charlin Change-Id: I0f82ebbf7b3301c6368462fb4fb4d4d02b246fc6 --- src/backends/aclCommon/ArmComputeTensorUtils.cpp | 14 ++-- .../test/Pooling2dEndToEndTestImpl.hpp | 23 ++++-- src/backends/cl/test/ClEndToEndTests.cpp | 52 ++++++++++++-- src/backends/gpuFsa/GpuFsaBackend.cpp | 8 +++ src/backends/gpuFsa/GpuFsaLayerSupport.cpp | 17 ++++- src/backends/gpuFsa/backend.cmake | 4 +- src/backends/gpuFsa/layers/CMakeLists.txt | 14 ++-- src/backends/gpuFsa/layers/GpuFsaConvolution2d.cpp | 45 +++--------- src/backends/gpuFsa/layers/GpuFsaConvolution2d.hpp | 3 - .../gpuFsa/layers/GpuFsaDepthwiseConvolution2d.cpp | 34 +++------ .../gpuFsa/layers/GpuFsaDepthwiseConvolution2d.hpp | 3 - .../gpuFsa/layers/GpuFsaElementwiseBinaryAdd.cpp | 9 +-- .../gpuFsa/layers/GpuFsaElementwiseBinaryAdd.hpp | 13 ++-- .../gpuFsa/layers/GpuFsaElementwiseBinarySub.cpp | 9 +-- .../gpuFsa/layers/GpuFsaElementwiseBinarySub.hpp | 15 ++-- src/backends/gpuFsa/layers/GpuFsaPooling2d.cpp | 83 ++++++++++++++++++++++ src/backends/gpuFsa/layers/GpuFsaPooling2d.hpp | 20 ++++++ src/backends/gpuFsa/layers/UtilsGpuFsa.cpp | 61 ++++++++++++++++ src/backends/gpuFsa/layers/UtilsGpuFsa.hpp | 30 ++++++++ src/backends/gpuFsa/test/GpuFsaEndToEndTests.cpp | 54 ++++++++++++++ .../gpuFsa/test/GpuFsaLayerSupportTests.cpp | 30 ++++++++ src/backends/neon/test/NeonEndToEndTests.cpp | 44 ++++++++++++ src/backends/reference/test/RefEndToEndTests.cpp | 46 +++++++++++- .../tosaReference/test/TosaRefEndToEndTests.cpp | 15 ++-- 24 files changed, 517 insertions(+), 129 deletions(-) create mode 100644 src/backends/gpuFsa/layers/GpuFsaPooling2d.cpp create mode 100644 src/backends/gpuFsa/layers/GpuFsaPooling2d.hpp create mode 100644 src/backends/gpuFsa/layers/UtilsGpuFsa.cpp create mode 100644 src/backends/gpuFsa/layers/UtilsGpuFsa.hpp diff --git a/src/backends/aclCommon/ArmComputeTensorUtils.cpp b/src/backends/aclCommon/ArmComputeTensorUtils.cpp index e6c5a9b41c..a11b966f34 100644 --- a/src/backends/aclCommon/ArmComputeTensorUtils.cpp +++ b/src/backends/aclCommon/ArmComputeTensorUtils.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2017-2024 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include @@ -276,12 +276,12 @@ arm_compute::PoolingLayerInfo BuildArmComputePoolingLayerInfo(const Pooling2dDes const arm_compute::DimensionRoundingType rounding = ConvertOutputShapeRoundingToAclDimensionRoundingType( descriptor.m_OutputShapeRounding); const arm_compute::PadStrideInfo padStrideInfo(descriptor.m_StrideX, - descriptor.m_StrideY, - descriptor.m_PadLeft, - descriptor.m_PadRight, - descriptor.m_PadTop, - descriptor.m_PadBottom, - rounding); + descriptor.m_StrideY, + descriptor.m_PadLeft, + descriptor.m_PadRight, + descriptor.m_PadTop, + descriptor.m_PadBottom, + rounding); const bool excludePadding = (descriptor.m_PaddingMethod == PaddingMethod::Exclude); diff --git a/src/backends/backendsCommon/test/Pooling2dEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/Pooling2dEndToEndTestImpl.hpp index 7a264e1bb0..adff6e03b8 100644 --- a/src/backends/backendsCommon/test/Pooling2dEndToEndTestImpl.hpp +++ b/src/backends/backendsCommon/test/Pooling2dEndToEndTestImpl.hpp @@ -76,7 +76,8 @@ void MaxPool2dEndToEnd(const std::vector& backends, } template -void MaxPool2dEndToEndFloat16(const std::vector& backends) +void MaxPool2dEndToEndFloat16(const std::vector& backends, + PaddingMethod padMethod = PaddingMethod::Exclude) { using namespace half_float::literal; using Half = half_float::half; @@ -84,7 +85,7 @@ void MaxPool2dEndToEndFloat16(const std::vector& backends) const TensorShape& inputShape = { 1, 3, 3, 1 }; const TensorShape& outputShape = { 1, 3, 3, 1 }; - INetworkPtr network = CreatePooling2dNetwork(inputShape, outputShape); + INetworkPtr network = CreatePooling2dNetwork(inputShape, outputShape, padMethod); CHECK(network); std::vector inputData{ 1._h, 2._h, 3._h, @@ -140,7 +141,7 @@ void AvgPool2dEndToEnd(const std::vector& backends, template void AvgPool2dEndToEndFloat16(const std::vector& backends, - PaddingMethod padMethod = PaddingMethod::IgnoreValue) + PaddingMethod padMethod = PaddingMethod::Exclude) { using namespace half_float::literal; using Half = half_float::half; @@ -155,9 +156,19 @@ void AvgPool2dEndToEndFloat16(const std::vector& backends, std::vector inputData{ 1._h, 2._h, 3._h, 4._h, 5._h, 6._h, 7._h, 8._h, 9._h }; - std::vector expectedOutput{ 1.33333_h, 2.33333_h, 1.77778_h, - 3._h , 5._h , 3.66667_h, - 2.66667_h, 4.33333_h, 3.11111_h }; + std::vector expectedOutput; + if (padMethod == PaddingMethod::Exclude) + { + expectedOutput = { 3._h , 3.5_h, 4._h , + 4.5_h, 5._h , 5.5_h, + 6._h , 6.5_h, 7._h }; + } + else + { + expectedOutput = { 1.33333_h, 2.33333_h, 1.77778_h, + 3._h , 5._h , 3.66667_h, + 2.66667_h, 4.33333_h, 3.11111_h }; + } std::map> inputTensorData = { { 0, inputData } }; std::map> expectedOutputData = { { 0, expectedOutput } }; diff --git a/src/backends/cl/test/ClEndToEndTests.cpp b/src/backends/cl/test/ClEndToEndTests.cpp index 878054f7ba..3acd7dc29b 100644 --- a/src/backends/cl/test/ClEndToEndTests.cpp +++ b/src/backends/cl/test/ClEndToEndTests.cpp @@ -17,6 +17,7 @@ #include #include #include +#include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp" #include #include #include @@ -245,8 +246,8 @@ TEST_CASE("ClGreaterSimpleEndToEndUint8Test") 0, 0, 0, 0, 0, 0, 0, 0 }); ComparisonSimpleEndToEnd(clDefaultBackends, - ComparisonOperation::Greater, - expectedOutput); + ComparisonOperation::Greater, + expectedOutput); } TEST_CASE("ClGreaterBroadcastEndToEndTest") @@ -265,8 +266,8 @@ TEST_CASE("ClGreaterBroadcastEndToEndUint8Test") 1, 1, 1, 1, 1, 1 }); ComparisonBroadcastEndToEnd(clDefaultBackends, - ComparisonOperation::Greater, - expectedOutput); + ComparisonOperation::Greater, + expectedOutput); } // HardSwish @@ -316,6 +317,49 @@ TEST_CASE("ClInstanceNormalizationNchwEndToEndTest2") InstanceNormalizationNchwEndToEndTest2(clDefaultBackends); } +// Pooling 2D +// Average Pool 2D +TEST_CASE("ClAvgPool2DEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(clDefaultBackends); +} + +TEST_CASE("ClAvgPool2DEndtoEndTestFloat16") +{ + AvgPool2dEndToEndFloat16(clDefaultBackends); +} + +TEST_CASE("ClAvgPool2DIgnoreValueEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(clDefaultBackends, PaddingMethod::IgnoreValue); +} + +// Max Pool 2D +TEST_CASE("ClMaxPool2DEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(clDefaultBackends); +} + +TEST_CASE("ClMaxPool2DEndtoEndTestFloat16") +{ + MaxPool2dEndToEndFloat16(clDefaultBackends); +} + +TEST_CASE("ClMaxPool2DIgnoreValueEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(clDefaultBackends, PaddingMethod::IgnoreValue); +} + +TEST_CASE("ClMaxPool2DTwoLayerEndtoEndTestFloat32") +{ + MaxPool2dTwoLayerEndToEnd(clDefaultBackends); +} + +TEST_CASE("ClMaxPool2DThreeLayerEndtoEndTestFloat32") +{ + MaxPool2dThreeLayerEndToEnd(clDefaultBackends); +} + // Fill TEST_CASE("ClFillEndToEndTest") { diff --git a/src/backends/gpuFsa/GpuFsaBackend.cpp b/src/backends/gpuFsa/GpuFsaBackend.cpp index 8b62aec9e6..f14687b8e0 100644 --- a/src/backends/gpuFsa/GpuFsaBackend.cpp +++ b/src/backends/gpuFsa/GpuFsaBackend.cpp @@ -24,6 +24,7 @@ #include "layers/GpuFsaDepthwiseConvolution2d.hpp" #include "layers/GpuFsaElementwiseBinaryAdd.hpp" #include "layers/GpuFsaElementwiseBinarySub.hpp" +#include "layers/GpuFsaPooling2d.hpp" namespace armnn { @@ -315,6 +316,13 @@ OptimizationViews GpuFsaBackend::OptimizeSubgraphView(const SubgraphView& subgra } break; } + case (LayerType::Pooling2d): + { + auto input = base.GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(); + auto desc = PolymorphicDowncast(&base.GetParameters()); + GpuFsaPooling2dCreateOp(preCompiledBlobPtr, input, *desc); + break; + } default: // unsupported layer for GpuFsa backend continue; diff --git a/src/backends/gpuFsa/GpuFsaLayerSupport.cpp b/src/backends/gpuFsa/GpuFsaLayerSupport.cpp index 2e5c7d5a53..b73b3e9088 100644 --- a/src/backends/gpuFsa/GpuFsaLayerSupport.cpp +++ b/src/backends/gpuFsa/GpuFsaLayerSupport.cpp @@ -14,6 +14,7 @@ #include "layers/GpuFsaDepthwiseConvolution2d.hpp" #include "layers/GpuFsaElementwiseBinaryAdd.hpp" #include "layers/GpuFsaElementwiseBinarySub.hpp" +#include "layers/GpuFsaPooling2d.hpp" #endif #include @@ -156,7 +157,21 @@ bool GpuFsaLayerSupport::IsLayerSupported(const LayerType& type, { throw InvalidArgumentException("Invalid ElementwiseBinary BinaryOperation operation."); } - return false; + } + case LayerType::Pooling2d: + { + if (infos.size() != 2) + { + throw InvalidArgumentException("Invalid number of Pooling2d TensorInfos. " + "TensorInfos should be of format: {input, output}."); + } + + auto desc = PolymorphicDowncast(&descriptor); + + FORWARD_LAYER_VALIDATE_FUNC(GpuFsaPooling2dValidate, + reasonIfUnsupported, + infos[0], + *desc); } case LayerType::Constant: case LayerType::Input: diff --git a/src/backends/gpuFsa/backend.cmake b/src/backends/gpuFsa/backend.cmake index 16473336e0..67e9be7fab 100644 --- a/src/backends/gpuFsa/backend.cmake +++ b/src/backends/gpuFsa/backend.cmake @@ -1,5 +1,5 @@ # -# Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. +# Copyright © 2022-2024 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # @@ -7,7 +7,7 @@ add_subdirectory(${PROJECT_SOURCE_DIR}/src/backends/gpuFsa) list(APPEND armnnLibraries armnnGpuFsaBackend) if(ARMCOMPUTEGPUFSA) - list(APPEND armnnLibraries armnnGpuFsaBackendLayerValidators) + list(APPEND armnnLibraries armnnGpuFsaBackendLayers) list(APPEND armnnLibraries armnnGpuFsaBackendWorkloads) list(APPEND armnnUnitTestLibraries armnnGpuFsaBackendUnitTests) else() diff --git a/src/backends/gpuFsa/layers/CMakeLists.txt b/src/backends/gpuFsa/layers/CMakeLists.txt index 182a32c121..5e0d0e7486 100644 --- a/src/backends/gpuFsa/layers/CMakeLists.txt +++ b/src/backends/gpuFsa/layers/CMakeLists.txt @@ -3,7 +3,7 @@ # SPDX-License-Identifier: MIT # -list(APPEND armnnGpuFsaBackendLayerValidators_sources +list(APPEND armnnGpuFsaBackendLayers_sources GpuFsaConvolution2d.cpp GpuFsaConvolution2d.hpp GpuFsaDepthwiseConvolution2d.cpp @@ -12,9 +12,13 @@ list(APPEND armnnGpuFsaBackendLayerValidators_sources GpuFsaElementwiseBinaryAdd.hpp GpuFsaElementwiseBinarySub.cpp GpuFsaElementwiseBinarySub.hpp + GpuFsaPooling2d.cpp + GpuFsaPooling2d.hpp + UtilsGpuFsa.cpp + UtilsGpuFsa.hpp ) -add_library(armnnGpuFsaBackendLayerValidators OBJECT ${armnnGpuFsaBackendLayerValidators_sources}) -target_include_directories(armnnGpuFsaBackendLayerValidators PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn) -target_include_directories(armnnGpuFsaBackendLayerValidators PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils) -target_include_directories(armnnGpuFsaBackendLayerValidators PRIVATE ${PROJECT_SOURCE_DIR}/src/backends) +add_library(armnnGpuFsaBackendLayers OBJECT ${armnnGpuFsaBackendLayers_sources}) +target_include_directories(armnnGpuFsaBackendLayers PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn) +target_include_directories(armnnGpuFsaBackendLayers PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils) +target_include_directories(armnnGpuFsaBackendLayers PRIVATE ${PROJECT_SOURCE_DIR}/src/backends) diff --git a/src/backends/gpuFsa/layers/GpuFsaConvolution2d.cpp b/src/backends/gpuFsa/layers/GpuFsaConvolution2d.cpp index 90b0ddc78c..e9409634ed 100644 --- a/src/backends/gpuFsa/layers/GpuFsaConvolution2d.cpp +++ b/src/backends/gpuFsa/layers/GpuFsaConvolution2d.cpp @@ -4,29 +4,23 @@ // #include "GpuFsaConvolution2d.hpp" - -//#include +#include "UtilsGpuFsa.hpp" #include -//#include -//#include -//#include -//#include -//#include - -//#include #include +#include #include #include #include +using namespace arm_compute::experimental::dynamic_fusion; +using namespace armnn::armcomputetensorutils; + namespace armnn { -using namespace armcomputetensorutils; - arm_compute::Status GpuFsaConvolution2dValidate(const TensorInfo& input, const Convolution2dDescriptor& descriptor, const TensorInfo& weights, @@ -61,23 +55,14 @@ arm_compute::Status GpuFsaConvolution2dValidate(const TensorInfo& input, biasSketchInfoPtr = workloadContext.create_tensor_info(aclBiasInfo); } - // Set Conv2d attributes using descriptor - const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX, - descriptor.m_DilationY); - const arm_compute::Padding2D aclPadInfo = BuildArmComputePaddingInfo(descriptor); - const arm_compute::Size2D aclStrideInfo = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); - - Conv2dAttributes conv2DAttributes{}; - conv2DAttributes.dilation(aclDilationInfo); - conv2DAttributes.pad(aclPadInfo); - conv2DAttributes.stride(aclStrideInfo); + Conv2dAttributes conv2dAttributes = CreateConv2dAttributes(descriptor); // Validate operator, check status and update reasonIfUnsupported arm_compute::Status aclStatus = GpuConv2d::validate_op(sketch, inputInfo, weightInfo, biasSketchInfoPtr, - conv2DAttributes); + conv2dAttributes); return aclStatus; } @@ -99,7 +84,6 @@ void GpuFsaConvolution2dCreateOp(GpuFsaPreCompiledBlob* blob, * as the TensorInfos used when creating the Tensors must match those used to create the Sketch. Otherwise the runtime * doesn't know which Tensors to use. */ - using namespace arm_compute::experimental::dynamic_fusion; GpuWorkloadSketch* sketch = blob->sketch.get(); GpuWorkloadContext* workloadContext = blob->workloadContext.get(); std::vector inputTensorInfos = {}; @@ -130,23 +114,14 @@ void GpuFsaConvolution2dCreateOp(GpuFsaPreCompiledBlob* blob, biasSketchInfoPtr = inputTensorInfos[2]; } - // Set Conv2d attributes using descriptor - const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX, - descriptor.m_DilationY); - const arm_compute::Padding2D aclPadInfo = BuildArmComputePaddingInfo(descriptor); - const arm_compute::Size2D aclStrideInfo = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); - - Conv2dAttributes conv2DAttributes{}; - conv2DAttributes.dilation(aclDilationInfo); - conv2DAttributes.pad(aclPadInfo); - conv2DAttributes.stride(aclStrideInfo); + Conv2dAttributes conv2dAttributes = CreateConv2dAttributes(descriptor); // Validate operator, check status and update reasonIfUnsupported arm_compute::Status aclStatus = GpuConv2d::validate_op(*sketch, inputTensorInfos[0], inputTensorInfos[1], biasSketchInfoPtr, - conv2DAttributes); + conv2dAttributes); const bool supported = (aclStatus.error_code() == arm_compute::ErrorCode::OK); if (!supported) @@ -159,7 +134,7 @@ void GpuFsaConvolution2dCreateOp(GpuFsaPreCompiledBlob* blob, inputTensorInfos[0], inputTensorInfos[1], biasSketchInfoPtr, - conv2DAttributes); + conv2dAttributes); // Create the Output outputTensorInfos.emplace_back(workloadContext->create_tensor_info()); diff --git a/src/backends/gpuFsa/layers/GpuFsaConvolution2d.hpp b/src/backends/gpuFsa/layers/GpuFsaConvolution2d.hpp index 424ba41f56..55067f0b5d 100644 --- a/src/backends/gpuFsa/layers/GpuFsaConvolution2d.hpp +++ b/src/backends/gpuFsa/layers/GpuFsaConvolution2d.hpp @@ -10,9 +10,6 @@ namespace armnn { - -using namespace arm_compute::experimental::dynamic_fusion; - arm_compute::Status GpuFsaConvolution2dValidate(const TensorInfo& input, const Convolution2dDescriptor& descriptor, const TensorInfo& weights, diff --git a/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.cpp b/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.cpp index a3c3dd9e44..21077afbfb 100644 --- a/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.cpp +++ b/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.cpp @@ -4,22 +4,25 @@ // #include "GpuFsaDepthwiseConvolution2d.hpp" +#include "UtilsGpuFsa.hpp" + #include #include -#include #include +#include #include #include #include +using namespace arm_compute::experimental::dynamic_fusion; +using namespace armnn::armcomputetensorutils; + namespace armnn { -using namespace armcomputetensorutils; - arm_compute::Status GpuFsaDepthwiseConvolution2dValidate(const TensorInfo& input, const DepthwiseConvolution2dDescriptor& descriptor, const TensorInfo& weights, @@ -71,17 +74,7 @@ arm_compute::Status GpuFsaDepthwiseConvolution2dValidate(const TensorInfo& input biasSketchInfoPtr = workloadContext.create_tensor_info(aclBiasInfo); } - // Set DepthwiseConv2d attributes using descriptor - const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX, - descriptor.m_DilationY); - const arm_compute::Padding2D aclPadInfo = BuildArmComputePaddingInfo(descriptor); - const arm_compute::Size2D aclStrideInfo = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); - - DepthwiseConv2dAttributes depthwiseConv2dAttributes{}; - depthwiseConv2dAttributes.pad(aclPadInfo); - depthwiseConv2dAttributes.stride(aclStrideInfo); - depthwiseConv2dAttributes.dilation(aclDilationInfo); - depthwiseConv2dAttributes.depth_multiplier(aclDepthMultiplier); + DepthwiseConv2dAttributes depthwiseConv2dAttributes = CreateDWConv2dAttributes(descriptor, aclDepthMultiplier); // Validate operator, check status and update reasonIfUnsupported arm_compute::Status aclStatus = GpuDepthwiseConv2d::validate_op(sketch, @@ -110,7 +103,6 @@ void GpuFsaDepthwiseConvolution2dCreateOp(GpuFsaPreCompiledBlob* blob, * as the TensorInfos used when creating the Tensors must match those used to create the Sketch. Otherwise the runtime * doesn't know which Tensors to use. */ - using namespace arm_compute::experimental::dynamic_fusion; GpuWorkloadSketch* sketch = blob->sketch.get(); GpuWorkloadContext* workloadContext = blob->workloadContext.get(); std::vector inputTensorInfos = {}; @@ -157,17 +149,7 @@ void GpuFsaDepthwiseConvolution2dCreateOp(GpuFsaPreCompiledBlob* blob, biasSketchInfoPtr = inputTensorInfos[2]; } - // Set DepthwiseConv2d attributes using descriptor - const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX, - descriptor.m_DilationY); - const arm_compute::Padding2D aclPadInfo = BuildArmComputePaddingInfo(descriptor); - const arm_compute::Size2D aclStrideInfo = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); - - DepthwiseConv2dAttributes depthwiseConv2dAttributes{}; - depthwiseConv2dAttributes.pad(aclPadInfo); - depthwiseConv2dAttributes.stride(aclStrideInfo); - depthwiseConv2dAttributes.dilation(aclDilationInfo); - depthwiseConv2dAttributes.depth_multiplier(aclDepthMultiplier); + DepthwiseConv2dAttributes depthwiseConv2dAttributes = CreateDWConv2dAttributes(descriptor, aclDepthMultiplier); // Validate operator, check status and update reasonIfUnsupported arm_compute::Status aclStatus = GpuDepthwiseConv2d::validate_op(*sketch, diff --git a/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.hpp b/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.hpp index d3e562d5a4..924d1d3999 100644 --- a/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.hpp +++ b/src/backends/gpuFsa/layers/GpuFsaDepthwiseConvolution2d.hpp @@ -10,9 +10,6 @@ namespace armnn { - -using namespace arm_compute::experimental::dynamic_fusion; - arm_compute::Status GpuFsaDepthwiseConvolution2dValidate(const TensorInfo& input, const DepthwiseConvolution2dDescriptor& descriptor, const TensorInfo& weights, diff --git a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.cpp b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.cpp index fa016a6815..d6404dd67e 100644 --- a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.cpp +++ b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.cpp @@ -7,12 +7,13 @@ #include -#include -#include #include #include +#include +#include using namespace arm_compute::experimental::dynamic_fusion; +using namespace armnn::armcomputetensorutils; namespace armnn { @@ -20,8 +21,6 @@ namespace armnn arm_compute::Status GpuFsaElementwiseBinaryAddValidate(const TensorInfo& input0, const TensorInfo& input1) { - using namespace armcomputetensorutils; - // Create a new workload sketch, for validation purposes auto compileCtx = arm_compute::CLKernelLibrary::get().get_compile_context(); auto workloadContext = GpuWorkloadContext(&compileCtx); @@ -43,8 +42,6 @@ void GpuFsaElementwiseBinaryAddCreateOp(GpuFsaPreCompiledBlob* blob, const TensorInfo& input0, const TensorInfo& input1) { - using namespace armcomputetensorutils; - GpuWorkloadSketch* sketch = blob->sketch.get(); GpuWorkloadContext* workloadContext = blob->workloadContext.get(); std::vector inputTensorInfos = {}; diff --git a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.hpp b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.hpp index 73f1fcbd58..1392d01257 100644 --- a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.hpp +++ b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinaryAdd.hpp @@ -10,14 +10,11 @@ namespace armnn { +arm_compute::Status GpuFsaElementwiseBinaryAddValidate(const TensorInfo& input0, + const TensorInfo& input1); - using namespace arm_compute::experimental::dynamic_fusion; - - arm_compute::Status GpuFsaElementwiseBinaryAddValidate(const TensorInfo& input0, - const TensorInfo& input1); - - void GpuFsaElementwiseBinaryAddCreateOp(GpuFsaPreCompiledBlob* blob, - const TensorInfo& input0, - const TensorInfo& input1); +void GpuFsaElementwiseBinaryAddCreateOp(GpuFsaPreCompiledBlob* blob, + const TensorInfo& input0, + const TensorInfo& input1); } // namespace armnn \ No newline at end of file diff --git a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.cpp b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.cpp index 4e7eb77190..5e0f478686 100644 --- a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.cpp +++ b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.cpp @@ -7,12 +7,13 @@ #include -#include -#include #include #include +#include +#include using namespace arm_compute::experimental::dynamic_fusion; +using namespace armnn::armcomputetensorutils; namespace armnn { @@ -20,8 +21,6 @@ namespace armnn arm_compute::Status GpuFsaElementwiseBinarySubValidate(const TensorInfo& input0, const TensorInfo& input1) { - using namespace armcomputetensorutils; - // Create a new workload sketch, for validation purposes auto compileCtx = arm_compute::CLKernelLibrary::get().get_compile_context(); auto workloadContext = GpuWorkloadContext(&compileCtx); @@ -43,8 +42,6 @@ void GpuFsaElementwiseBinarySubCreateOp(GpuFsaPreCompiledBlob* blob, const TensorInfo& input0, const TensorInfo& input1) { - using namespace armcomputetensorutils; - GpuWorkloadSketch* sketch = blob->sketch.get(); GpuWorkloadContext* workloadContext = blob->workloadContext.get(); std::vector inputTensorInfos = {}; diff --git a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.hpp b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.hpp index 59d8189f1f..4d58f313b6 100644 --- a/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.hpp +++ b/src/backends/gpuFsa/layers/GpuFsaElementwiseBinarySub.hpp @@ -2,7 +2,6 @@ // Copyright © 2024 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // - #pragma once #include @@ -11,13 +10,11 @@ namespace armnn { +arm_compute::Status GpuFsaElementwiseBinarySubValidate(const TensorInfo& input0, + const TensorInfo& input1); - using namespace arm_compute::experimental::dynamic_fusion; - - arm_compute::Status GpuFsaElementwiseBinarySubValidate(const TensorInfo& input0, - const TensorInfo& input1); +void GpuFsaElementwiseBinarySubCreateOp(GpuFsaPreCompiledBlob* blob, + const TensorInfo& input0, + const TensorInfo& input1); - void GpuFsaElementwiseBinarySubCreateOp(GpuFsaPreCompiledBlob* blob, - const TensorInfo& input0, - const TensorInfo& input1); -} \ No newline at end of file +} // namespace armnn \ No newline at end of file diff --git a/src/backends/gpuFsa/layers/GpuFsaPooling2d.cpp b/src/backends/gpuFsa/layers/GpuFsaPooling2d.cpp new file mode 100644 index 0000000000..4575d21421 --- /dev/null +++ b/src/backends/gpuFsa/layers/GpuFsaPooling2d.cpp @@ -0,0 +1,83 @@ +// +// Copyright © 2024 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "GpuFsaPooling2d.hpp" +#include "UtilsGpuFsa.hpp" + +#include + +#include +#include +#include +#include + +using namespace arm_compute::experimental::dynamic_fusion; +using namespace armnn::armcomputetensorutils; + +namespace armnn +{ + +arm_compute::Status GpuFsaPooling2dValidate(const TensorInfo& input, + const Pooling2dDescriptor& descriptor) +{ + // Create a new workload sketch, for validation purposes + auto compileCtx = arm_compute::CLKernelLibrary::get().get_compile_context(); + auto workloadContext = GpuWorkloadContext(&compileCtx); + GpuWorkloadSketch sketch{ &workloadContext }; + + arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout); + aclInputInfo.set_are_values_constant(input.IsConstant()); + arm_compute::ITensorInfo* inputInfo = workloadContext.create_tensor_info(aclInputInfo); + + Pool2dAttributes pool2dAttributes = CreatePool2dAttributes(descriptor); + GpuPool2dSettings pool2dSettings{}; + + return GpuPool2d::validate_op(sketch, inputInfo, pool2dAttributes, pool2dSettings); +} + +void GpuFsaPooling2dCreateOp(GpuFsaPreCompiledBlob* blob, + const TensorInfo& input, + const Pooling2dDescriptor& descriptor) +{ + GpuWorkloadSketch* sketch = blob->sketch.get(); + GpuWorkloadContext* workloadContext = blob->workloadContext.get(); + std::vector inputTensorInfos = {}; + std::vector outputTensorInfos = {}; + + arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout); + aclInputInfo.set_are_values_constant(input.IsConstant()); + + inputTensorInfos.emplace_back(workloadContext->create_tensor_info(aclInputInfo)); + + Pool2dAttributes pool2dAttributes = CreatePool2dAttributes(descriptor); + GpuPool2dSettings pool2dSettings{}; + + // Validate operator, check status and update reasonIfUnsupported + arm_compute::Status aclStatus = GpuPool2d::validate_op(*sketch, + inputTensorInfos[0], + pool2dAttributes, + pool2dSettings); + + const bool supported = aclStatus.error_code() == arm_compute::ErrorCode::OK; + if (!supported) + { + throw BackendCapabilityException("\"GpuFsa\" backend failed during pooling 2d validation"); + } + + arm_compute::ITensorInfo* addOutputInfo = GpuPool2d::create_op(*sketch, + inputTensorInfos[0], + pool2dAttributes, + pool2dSettings); + + // Temporary fix until fusing attempt is make for GpuFsa backend and Output layer workload is created. + outputTensorInfos.emplace_back(workloadContext->create_tensor_info()); + GpuOutput::create_op(*sketch, addOutputInfo, outputTensorInfos[0]); + + // Store the TensorInfos within the blob as unique_ptrs to be used later + blob->inputTensorInfos = std::make_unique>(inputTensorInfos); + blob->outputTensorInfos = std::make_unique>(outputTensorInfos); +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/gpuFsa/layers/GpuFsaPooling2d.hpp b/src/backends/gpuFsa/layers/GpuFsaPooling2d.hpp new file mode 100644 index 0000000000..25f6e72cd0 --- /dev/null +++ b/src/backends/gpuFsa/layers/GpuFsaPooling2d.hpp @@ -0,0 +1,20 @@ +// +// Copyright © 2024 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include + +#include + +namespace armnn +{ +arm_compute::Status GpuFsaPooling2dValidate(const TensorInfo& input, + const Pooling2dDescriptor& descriptor); + +void GpuFsaPooling2dCreateOp(GpuFsaPreCompiledBlob* blob, + const TensorInfo& input, + const Pooling2dDescriptor& descriptor); + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/gpuFsa/layers/UtilsGpuFsa.cpp b/src/backends/gpuFsa/layers/UtilsGpuFsa.cpp new file mode 100644 index 0000000000..a1d96f0ec1 --- /dev/null +++ b/src/backends/gpuFsa/layers/UtilsGpuFsa.cpp @@ -0,0 +1,61 @@ +// +// Copyright © 2023-2024 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "UtilsGpuFsa.hpp" +#include "aclCommon/ArmComputeTensorUtils.hpp" +#include "aclCommon/ArmComputeUtils.hpp" + +using namespace armnn; +using namespace armnn::armcomputetensorutils; +using namespace arm_compute::experimental::dynamic_fusion; + +Conv2dAttributes CreateConv2dAttributes(const Convolution2dDescriptor& descriptor) +{ + const arm_compute::Padding2D padInfo = BuildArmComputePaddingInfo(descriptor); + const arm_compute::Size2D strideInfo = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); + const arm_compute::Size2D dilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX, descriptor.m_DilationY); + + arm_compute::experimental::dynamic_fusion::Conv2dAttributes conv2dAttributes{}; + conv2dAttributes.pad(padInfo); + conv2dAttributes.stride(strideInfo); + conv2dAttributes.dilation(dilationInfo); + + return conv2dAttributes; +} + +arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes +CreateDWConv2dAttributes(const DepthwiseConvolution2dDescriptor& descriptor, const unsigned int aclDepthMultiplier) +{ + const arm_compute::Padding2D padInfo = BuildArmComputePaddingInfo(descriptor); + const arm_compute::Size2D strideInfo = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); + const arm_compute::Size2D dilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX, descriptor.m_DilationY); + + arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes depthwiseConv2dAttributes{}; + depthwiseConv2dAttributes.pad(padInfo); + depthwiseConv2dAttributes.stride(strideInfo); + depthwiseConv2dAttributes.dilation(dilationInfo); + depthwiseConv2dAttributes.depth_multiplier(aclDepthMultiplier); + + return depthwiseConv2dAttributes; +} + +arm_compute::experimental::dynamic_fusion::Pool2dAttributes +CreatePool2dAttributes(const Pooling2dDescriptor& descriptor) +{ + const arm_compute::PoolingType poolType = ConvertPoolingAlgorithmToAclPoolingType(descriptor.m_PoolType); + const arm_compute::Padding2D padding = BuildArmComputePaddingInfo(descriptor); + const arm_compute::Size2D poolSize = BuildArmComputeSize2D(descriptor.m_PoolWidth, descriptor.m_PoolHeight); + const arm_compute::Size2D strides = BuildArmComputeSize2D(descriptor.m_StrideX, descriptor.m_StrideY); + const bool excludePadding = (descriptor.m_PaddingMethod == PaddingMethod::Exclude); + + arm_compute::experimental::dynamic_fusion::Pool2dAttributes pool2dAttributes{}; + pool2dAttributes.pool_type(poolType); + pool2dAttributes.pad(padding); + pool2dAttributes.pool_size(poolSize); + pool2dAttributes.stride(strides); + pool2dAttributes.exclude_padding(excludePadding); + + return pool2dAttributes; +} \ No newline at end of file diff --git a/src/backends/gpuFsa/layers/UtilsGpuFsa.hpp b/src/backends/gpuFsa/layers/UtilsGpuFsa.hpp new file mode 100644 index 0000000000..6c1d97ad87 --- /dev/null +++ b/src/backends/gpuFsa/layers/UtilsGpuFsa.hpp @@ -0,0 +1,30 @@ +// +// Copyright © 2023-2024 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "armnn/Descriptors.hpp" +#include "arm_compute/dynamic_fusion/sketch/attributes/Conv2dAttributes.h" +#include "arm_compute/dynamic_fusion/sketch/attributes/DepthwiseConv2dAttributes.h" +#include "arm_compute/dynamic_fusion/sketch/attributes/Pool2dAttributes.h" + +/// Utility function used to setup an arm_compute::Conv2dAttributes object from given descriptor +/// @param[in] armnn::Convolution2dDescriptor +/// @return arm_compute::experimental::dynamic_fusion::Conv2dAttributes +arm_compute::experimental::dynamic_fusion::Conv2dAttributes +CreateConv2dAttributes(const armnn::Convolution2dDescriptor& descriptor); + +/// Utility function used to setup an arm_compute::DepthwiseConv2dAttributes object from given descriptor +/// @param[in] armnn::DepthwiseConvolution2dDescriptor +/// @return arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes +arm_compute::experimental::dynamic_fusion::DepthwiseConv2dAttributes +CreateDWConv2dAttributes(const armnn::DepthwiseConvolution2dDescriptor& descriptor, + const unsigned int aclDepthMultiplier); + +/// Utility function used to setup an arm_compute::Pool2dAttributes object from given descriptor +/// @param[in] armnn::Pooling2dDescriptor +/// @return arm_compute::experimental::dynamic_fusion::Pool2dAttributes +arm_compute::experimental::dynamic_fusion::Pool2dAttributes +CreatePool2dAttributes(const armnn::Pooling2dDescriptor& descriptor); diff --git a/src/backends/gpuFsa/test/GpuFsaEndToEndTests.cpp b/src/backends/gpuFsa/test/GpuFsaEndToEndTests.cpp index 26c7cb8d63..93a4a81f9d 100644 --- a/src/backends/gpuFsa/test/GpuFsaEndToEndTests.cpp +++ b/src/backends/gpuFsa/test/GpuFsaEndToEndTests.cpp @@ -9,6 +9,8 @@ #include "backendsCommon/test/DepthwiseConvolution2dEndToEndTests.hpp" #include "backendsCommon/test/ElementwiseBinaryEndToEndTestImpl.hpp" +#include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp" + #include @@ -56,4 +58,56 @@ TEST_CASE("GpuFsaElementwiseBinarySubTestFloat16") ElementwiseBinarySimple3DEndToEnd(gpuFsaDefaultBackends, BinaryOperation::Sub); } +// Pooling 2D +// Average Pool 2D +TEST_CASE("GpuFsaAvgPool2DEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(gpuFsaDefaultBackends); +} + +TEST_CASE("GpuFsaAvgPool2DEndtoEndTestFloat16") +{ + + AvgPool2dEndToEndFloat16(gpuFsaDefaultBackends); +} + +TEST_CASE("UNSUPPORTED_GpuFsaAvgPool2DIgnoreValueEndtoEndTestFloat32") +{ + // Exclude padding must be set to true in Attributes! to be supported by GPU + try + { + AvgPool2dEndToEnd(gpuFsaDefaultBackends, PaddingMethod::IgnoreValue); + FAIL("An exception should have been thrown"); + } + catch (const armnn::InvalidArgumentException& e) + { + CHECK(strcmp(e.what(), "Failed to assign a backend to each layer") == 0); + } +} + +// Max Pool 2D +TEST_CASE("GpuFsaMaxPool2DEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(gpuFsaDefaultBackends); +} + +TEST_CASE("GpuFsaMaxPool2DEndtoEndTestFloat16") +{ + MaxPool2dEndToEndFloat16(gpuFsaDefaultBackends); +} + +TEST_CASE("UNSUPPORTED_GpuFsaMaxPool2DIgnoreValueEndtoEndTestFloat32") +{ + // Exclude padding must be set to true in Attributes! to be supported by GPU + try + { + MaxPool2dEndToEnd(gpuFsaDefaultBackends, PaddingMethod::IgnoreValue); + FAIL("An exception should have been thrown"); + } + catch (const armnn::InvalidArgumentException& e) + { + CHECK(strcmp(e.what(), "Failed to assign a backend to each layer") == 0); + } +} + } diff --git a/src/backends/gpuFsa/test/GpuFsaLayerSupportTests.cpp b/src/backends/gpuFsa/test/GpuFsaLayerSupportTests.cpp index 9d4b3b9367..fee0d07820 100644 --- a/src/backends/gpuFsa/test/GpuFsaLayerSupportTests.cpp +++ b/src/backends/gpuFsa/test/GpuFsaLayerSupportTests.cpp @@ -101,4 +101,34 @@ TEST_CASE("IsLayerSupportedGpuFsaElementWiseBinarySub") CHECK(supported); } +TEST_CASE("IsLayerSupportedGpuFsaPooling2d") +{ + TensorInfo inputInfo({ 1, 3, 4, 1 }, DataType::Float32); + TensorInfo outputInfo({ 1, 2, 2, 1 }, DataType::Float32); + + Pooling2dDescriptor desc{}; + desc.m_PoolType = PoolingAlgorithm::Max; + desc.m_PadLeft = 0; + desc.m_PadRight = 0; + desc.m_PadTop = 0; + desc.m_PadBottom = 0; + desc.m_PoolWidth = 2; + desc.m_PoolHeight = 2; + desc.m_StrideX = 1; + desc.m_StrideY = 1; + desc.m_OutputShapeRounding = OutputShapeRounding::Floor; + desc.m_PaddingMethod = PaddingMethod::Exclude; + desc.m_DataLayout = DataLayout::NHWC; + + GpuFsaLayerSupport supportChecker; + std::string reasonIfNotSupported; + auto supported = supportChecker.IsLayerSupported(LayerType::Pooling2d, + {inputInfo, outputInfo}, + desc, + EmptyOptional(), + EmptyOptional(), + reasonIfNotSupported); + CHECK(supported); +} + } \ No newline at end of file diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp index 37f6d3845b..1bf9344883 100644 --- a/src/backends/neon/test/NeonEndToEndTests.cpp +++ b/src/backends/neon/test/NeonEndToEndTests.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp" #include #include #include @@ -552,6 +553,49 @@ TEST_CASE("NeonInstanceNormalizationNchwEndToEndTest2") InstanceNormalizationNchwEndToEndTest2(neonDefaultBackends); } +// Pooling 2D +// Average Pool 2D +TEST_CASE("NeonAvgPool2DEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(neonDefaultBackends); +} + +TEST_CASE("NeonAvgPool2DEndtoEndTestFloat16") +{ + AvgPool2dEndToEndFloat16(neonDefaultBackends); +} + +TEST_CASE("NeonAvgPool2DIgnoreValueEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(neonDefaultBackends, PaddingMethod::IgnoreValue); +} + +// Max Pool 2D +TEST_CASE("NeonMaxPool2DEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(neonDefaultBackends); +} + +TEST_CASE("NeonMaxPool2DEndtoEndTestFloat16") +{ + MaxPool2dEndToEndFloat16(neonDefaultBackends); +} + +TEST_CASE("NeonMaxPool2DIgnoreValueEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(neonDefaultBackends, PaddingMethod::IgnoreValue); +} + +TEST_CASE("NeonMaxPool2DTwoLayerEndtoEndTestFloat32") +{ + MaxPool2dTwoLayerEndToEnd(neonDefaultBackends); +} + +TEST_CASE("NeonMaxPool2DThreeLayerEndtoEndTestFloat32") +{ + MaxPool2dThreeLayerEndToEnd(neonDefaultBackends); +} + // Fill TEST_CASE("NeonFillEndToEndTest") { diff --git a/src/backends/reference/test/RefEndToEndTests.cpp b/src/backends/reference/test/RefEndToEndTests.cpp index c09304e4d1..9f80059712 100644 --- a/src/backends/reference/test/RefEndToEndTests.cpp +++ b/src/backends/reference/test/RefEndToEndTests.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp" #include #include #include @@ -1098,6 +1099,49 @@ TEST_CASE("RefPreluEndToEndTestQSymm16") PreluEndToEndPositiveTest(defaultBackends); } +// Pooling 2D +// Average Pool 2D +TEST_CASE("RefAvgPool2DEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(defaultBackends); +} + +TEST_CASE("RefAvgPool2DEndtoEndTestFloat16") +{ + AvgPool2dEndToEndFloat16(defaultBackends); +} + +TEST_CASE("RefAvgPool2DIgnoreValueEndtoEndTestFloat32") +{ + AvgPool2dEndToEnd(defaultBackends, PaddingMethod::IgnoreValue); +} + +// Max Pool 2D +TEST_CASE("RefMaxPool2DEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(defaultBackends); +} + +TEST_CASE("RefMaxPool2DEndtoEndTestFloat16") +{ + MaxPool2dEndToEndFloat16(defaultBackends); +} + +TEST_CASE("RefMaxPool2DIgnoreValueEndtoEndTestFloat32") +{ + MaxPool2dEndToEnd(defaultBackends, PaddingMethod::IgnoreValue); +} + +TEST_CASE("RefMaxPool2DTwoLayerEndtoEndTestFloat32") +{ + MaxPool2dTwoLayerEndToEnd(defaultBackends); +} + +TEST_CASE("RefMaxPool2DThreeLayerEndtoEndTestFloat32") +{ + MaxPool2dThreeLayerEndToEnd(defaultBackends); +} + // Quantization TEST_CASE("QuantizationEndToEndFloat32_U8Test") { @@ -1156,7 +1200,7 @@ TEST_CASE("RefSplit1dEndtoEndTestSigned16") Splitter1dEndToEnd(defaultBackends); } -TEST_CASE("TosaRefSplit1dEndtoEndTestFloat16") +TEST_CASE("RefSplit1dEndtoEndTestFloat16") { Splitter1dEndToEndFloat16(defaultBackends); } diff --git a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp index 7a3edaf212..68531f89ff 100644 --- a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp +++ b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp @@ -95,6 +95,14 @@ TEST_CASE("TosaRefConv2dWithoutBiasEndtoEndTestFloat32") Convolution2dEndToEnd(tosaDefaultBackends, armnn::DataLayout::NHWC, false); } +// Maximum +TEST_CASE("TosaRefMaximumEndtoEndTestInt8") +{ + ElementwiseBinarySimpleNoReshapeEndToEnd(tosaDefaultBackends, + armnn::BinaryOperation::Maximum); +} + +// Pooling // Average Pool 2D TEST_CASE("TosaRefAvgPool2DEndtoEndTestFloat32") { @@ -111,13 +119,6 @@ TEST_CASE("TosaRefAvgPool2DIgnoreValueEndtoEndTestFloat32") AvgPool2dEndToEnd(tosaDefaultBackends, PaddingMethod::IgnoreValue); } -// Maximum -TEST_CASE("TosaRefMaximumEndtoEndTestInt8") -{ - ElementwiseBinarySimpleNoReshapeEndToEnd(tosaDefaultBackends, - armnn::BinaryOperation::Maximum); -} - // Max Pool 2D TEST_CASE("TosaRefMaxPool2DEndtoEndTestFloat32") { -- cgit v1.2.1