From 21a9f33338c60ae1cd955df220ce329918adcb8f Mon Sep 17 00:00:00 2001 From: Tianle Cheng Date: Thu, 9 Nov 2023 13:56:53 +0000 Subject: IVGCVSW-7835 Add ReverseV2 CL and Neon Workloads * Added ReverseV2 to CL and Neon backends * Added Cl and Neon ReverseV2 Layer unit tests Signed-off-by: Tianle Cheng Change-Id: I646275c629caf17dac1950b0cd7083f23f87f387 --- delegate/test/ReverseV2Test.cpp | 278 ++++++++++----------- src/backends/aclCommon/ArmComputeUtils.hpp | 16 +- src/backends/backendsCommon/WorkloadUtils.cpp | 2 +- .../test/layerTests/ReverseV2TestImpl.cpp | 149 +++++------ src/backends/cl/ClLayerSupport.cpp | 18 ++ src/backends/cl/ClLayerSupport.hpp | 5 + src/backends/cl/ClWorkloadFactory.cpp | 5 + src/backends/cl/backend.mk | 1 + src/backends/cl/test/ClEndToEndTests.cpp | 7 + src/backends/cl/test/ClLayerTests.cpp | 29 +++ src/backends/cl/workloads/CMakeLists.txt | 2 + src/backends/cl/workloads/ClReverseV2Workload.cpp | 50 ++++ src/backends/cl/workloads/ClReverseV2Workload.hpp | 33 +++ src/backends/cl/workloads/ClWorkloads.hpp | 1 + src/backends/neon/NeonLayerSupport.cpp | 18 ++ src/backends/neon/NeonLayerSupport.hpp | 7 +- src/backends/neon/NeonWorkloadFactory.cpp | 5 + src/backends/neon/backend.mk | 1 + src/backends/neon/test/NeonEndToEndTests.cpp | 7 + src/backends/neon/test/NeonLayerTests.cpp | 30 +++ src/backends/neon/workloads/CMakeLists.txt | 2 + .../neon/workloads/NeonReverseV2Workload.cpp | 44 ++++ .../neon/workloads/NeonReverseV2Workload.hpp | 29 +++ src/backends/neon/workloads/NeonWorkloads.hpp | 1 + .../reference/workloads/RefReverseV2Workload.cpp | 2 +- 25 files changed, 508 insertions(+), 234 deletions(-) create mode 100644 src/backends/cl/workloads/ClReverseV2Workload.cpp create mode 100644 src/backends/cl/workloads/ClReverseV2Workload.hpp create mode 100644 src/backends/neon/workloads/NeonReverseV2Workload.cpp create mode 100644 src/backends/neon/workloads/NeonReverseV2Workload.hpp diff --git a/delegate/test/ReverseV2Test.cpp b/delegate/test/ReverseV2Test.cpp index b261474e99..430cf2c7c7 100644 --- a/delegate/test/ReverseV2Test.cpp +++ b/delegate/test/ReverseV2Test.cpp @@ -19,165 +19,159 @@ namespace armnnDelegate { - void ReverseV2Float32Test(std::vector& backends) +void ReverseV2Float32Test(std::vector& backends) +{ + // Set input data + std::vector inputValues = { - // Set input data - std::vector inputValues = - { - 1.0f, 2.0f, 3.0f, - 4.0f, 5.0f, 6.0f, - 7.0f, 8.0f, 9.0f, - - 11.0f, 12.0f, 13.0f, - 14.0f, 15.0f, 16.0f, - 17.0f, 18.0f, 19.0f, - - 21.0f, 22.0f, 23.0f, - 24.0f, 25.0f, 26.0f, - 27.0f, 28.0f, 29.0f - }; - - // The output data - std::vector expectedOutputValues = - { - 3.0f, 2.0f, 1.0f, - 6.0f, 5.0f, 4.0f, - 9.0f, 8.0f, 7.0f, - - 13.0f, 12.0f, 11.0f, - 16.0f, 15.0f, 14.0f, - 19.0f, 18.0f, 17.0f, - - 23.0f, 22.0f, 21.0f, - 26.0f, 25.0f, 24.0f, - 29.0f, 28.0f, 27.0f - }; - - // The axis to reverse - const std::vector axisValues = {2}; - - // Shapes - const std::vector inputShape = {3, 3, 3}; - const std::vector axisShapeDims = {1}; - const std::vector expectedOutputShape = {3, 3, 3}; - - ReverseV2FP32TestImpl(tflite::BuiltinOperator_REVERSE_V2, - backends, - inputValues, - inputShape, - axisValues, - axisShapeDims, - expectedOutputValues, - expectedOutputShape); - } + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, - void ReverseV2NegativeAxisFloat32Test(std::vector& backends) - { - // Set input data - std::vector inputValues = - { - 1.0f, 2.0f, 3.0f, - 4.0f, 5.0f, 6.0f, - 7.0f, 8.0f, 9.0f, - - 11.0f, 12.0f, 13.0f, - 14.0f, 15.0f, 16.0f, - 17.0f, 18.0f, 19.0f, - - 21.0f, 22.0f, 23.0f, - 24.0f, 25.0f, 26.0f, - 27.0f, 28.0f, 29.0f - }; - - // The output data - std::vector expectedOutputValues = - { - 7.0f, 8.0f, 9.0f, - 4.0f, 5.0f, 6.0f, - 1.0f, 2.0f, 3.0f, - - 17.0f, 18.0f, 19.0f, - 14.0f, 15.0f, 16.0f, - 11.0f, 12.0f, 13.0f, - - 27.0f, 28.0f, 29.0f, - 24.0f, 25.0f, 26.0f, - 21.0f, 22.0f, 23.0f - }; - - // The axis to reverse - const std::vector axisValues = {-2}; - - // Shapes - const std::vector inputShape = {3, 3, 3}; - const std::vector axisShapeDims = {1}; - const std::vector expectedOutputShape = {3, 3, 3}; - - ReverseV2FP32TestImpl(tflite::BuiltinOperator_REVERSE_V2, - backends, - inputValues, - inputShape, - axisValues, - axisShapeDims, - expectedOutputValues, - expectedOutputShape); - } + 11.0f, 12.0f, 13.0f, + 14.0f, 15.0f, 16.0f, + 17.0f, 18.0f, 19.0f, -#if defined(REVERSEV2_GPUACC) - TEST_SUITE("ReverseV2Tests_GpuAccTests") - { + 21.0f, 22.0f, 23.0f, + 24.0f, 25.0f, 26.0f, + 27.0f, 28.0f, 29.0f + }; - TEST_CASE ("ReverseV2_Float32_GpuAcc_Test") - { - std::vector backends = { armnn::Compute::GpuAcc }; - ReverseV2Float32Test(backends); - } + // The output data + std::vector expectedOutputValues = + { + 3.0f, 2.0f, 1.0f, + 6.0f, 5.0f, 4.0f, + 9.0f, 8.0f, 7.0f, + + 13.0f, 12.0f, 11.0f, + 16.0f, 15.0f, 14.0f, + 19.0f, 18.0f, 17.0f, + + 23.0f, 22.0f, 21.0f, + 26.0f, 25.0f, 24.0f, + 29.0f, 28.0f, 27.0f + }; + + // The axis to reverse + const std::vector axisValues = {2}; + + // Shapes + const std::vector inputShape = {3, 3, 3}; + const std::vector axisShapeDims = {1}; + const std::vector expectedOutputShape = {3, 3, 3}; + + ReverseV2FP32TestImpl(tflite::BuiltinOperator_REVERSE_V2, + backends, + inputValues, + inputShape, + axisValues, + axisShapeDims, + expectedOutputValues, + expectedOutputShape); +} + +void ReverseV2NegativeAxisFloat32Test(std::vector& backends) +{ + // Set input data + std::vector inputValues = + { + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, - TEST_CASE ("ReverseV2_NegativeAxis_Float32_GpuAcc_Test") - { - std::vector backends = { armnn::Compute::GpuAcc }; - ReverseV2NegativeAxisFloat32Test(backends); - } + 11.0f, 12.0f, 13.0f, + 14.0f, 15.0f, 16.0f, + 17.0f, 18.0f, 19.0f, - } // TEST_SUITE("ReverseV2Tests_GpuAccTests") -#endif + 21.0f, 22.0f, 23.0f, + 24.0f, 25.0f, 26.0f, + 27.0f, 28.0f, 29.0f + }; + // The output data + std::vector expectedOutputValues = + { + 7.0f, 8.0f, 9.0f, + 4.0f, 5.0f, 6.0f, + 1.0f, 2.0f, 3.0f, + + 17.0f, 18.0f, 19.0f, + 14.0f, 15.0f, 16.0f, + 11.0f, 12.0f, 13.0f, + + 27.0f, 28.0f, 29.0f, + 24.0f, 25.0f, 26.0f, + 21.0f, 22.0f, 23.0f + }; + + // The axis to reverse + const std::vector axisValues = {-2}; + + // Shapes + const std::vector inputShape = {3, 3, 3}; + const std::vector axisShapeDims = {1}; + const std::vector expectedOutputShape = {3, 3, 3}; + + ReverseV2FP32TestImpl(tflite::BuiltinOperator_REVERSE_V2, + backends, + inputValues, + inputShape, + axisValues, + axisShapeDims, + expectedOutputValues, + expectedOutputShape); +} + +TEST_SUITE("ReverseV2Tests_GpuAccTests") +{ -#if defined(REVERSEV2_CPUACC) - TEST_SUITE("ReverseV2Tests_CpuAccTests") + TEST_CASE ("ReverseV2_Float32_GpuAcc_Test") { + std::vector backends = { armnn::Compute::GpuAcc }; + ReverseV2Float32Test(backends); + } - TEST_CASE ("ReverseV2_Float32_CpuAcc_Test") - { - std::vector backends = { armnn::Compute::CpuAcc }; - ReverseV2Float32Test(backends); - } + TEST_CASE ("ReverseV2_NegativeAxis_Float32_GpuAcc_Test") + { + std::vector backends = { armnn::Compute::GpuAcc }; + ReverseV2NegativeAxisFloat32Test(backends); + } - TEST_CASE ("ReverseV2_NegativeAxis_Float32_CpuAcc_Test") - { - std::vector backends = { armnn::Compute::CpuAcc }; - ReverseV2NegativeAxisFloat32Test(backends); - } +} // TEST_SUITE("ReverseV2Tests_GpuAccTests") - } // TEST_SUITE("ReverseV2Tests_CpuAccTests") -#endif +TEST_SUITE("ReverseV2Tests_CpuAccTests") +{ + TEST_CASE ("ReverseV2_Float32_CpuAcc_Test") + { + std::vector backends = { armnn::Compute::CpuAcc }; + ReverseV2Float32Test(backends); + } - TEST_SUITE("ReverseV2Tests_CpuRefTests") + TEST_CASE ("ReverseV2_NegativeAxis_Float32_CpuAcc_Test") { + std::vector backends = { armnn::Compute::CpuAcc }; + ReverseV2NegativeAxisFloat32Test(backends); + } + +} // TEST_SUITE("ReverseV2Tests_CpuAccTests") - TEST_CASE ("ReverseV2_Float32_CpuRef_Test") - { - std::vector backends = { armnn::Compute::CpuRef }; - ReverseV2Float32Test(backends); - } +TEST_SUITE("ReverseV2Tests_CpuRefTests") +{ + + TEST_CASE ("ReverseV2_Float32_CpuRef_Test") + { + std::vector backends = { armnn::Compute::CpuRef }; + ReverseV2Float32Test(backends); + } - TEST_CASE ("ReverseV2_NegativeAxis_Float32_CpuRef_Test") - { - std::vector backends = { armnn::Compute::CpuRef }; - ReverseV2NegativeAxisFloat32Test(backends); - } + TEST_CASE ("ReverseV2_NegativeAxis_Float32_CpuRef_Test") + { + std::vector backends = { armnn::Compute::CpuRef }; + ReverseV2NegativeAxisFloat32Test(backends); + } - } // TEST_SUITE("ReverseV2Tests_CpuRefTests") +} // TEST_SUITE("ReverseV2Tests_CpuRefTests") } // namespace armnnDelegate diff --git a/src/backends/aclCommon/ArmComputeUtils.hpp b/src/backends/aclCommon/ArmComputeUtils.hpp index 5d424afa9a..9a30a7456e 100644 --- a/src/backends/aclCommon/ArmComputeUtils.hpp +++ b/src/backends/aclCommon/ArmComputeUtils.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017-2023 Arm Ltd. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -284,20 +284,6 @@ inline int ComputeAclAxis(const int& armnnAxis, const armnn::TensorInfo& tensor) return aclAxis; } -/// Function to convert axis to its positive equivalent value. -/// [-rank, rank) --> [0, rank) -inline unsigned int ComputePositiveAxis(const int& axis, const armnn::TensorInfo& tensor) -{ - int rank = static_cast(tensor.GetNumDimensions()); - - ARMNN_ASSERT(rank != 0); - ARMNN_ASSERT((-1 * rank) <= axis); - ARMNN_ASSERT(axis < rank); - - int positiveAxis = (axis < 0) ? rank + axis : axis; - return static_cast(positiveAxis); -} - /// Utility function used to setup an arm_compute::Conv3dInfo object from convolution3d descriptor. inline arm_compute::Conv3dInfo ComputeConv3DInfo(const armnn::Convolution3dDescriptor descriptor, bool isFastMathEnabled, diff --git a/src/backends/backendsCommon/WorkloadUtils.cpp b/src/backends/backendsCommon/WorkloadUtils.cpp index 28d01ec127..e36c4b2128 100644 --- a/src/backends/backendsCommon/WorkloadUtils.cpp +++ b/src/backends/backendsCommon/WorkloadUtils.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd. All rights reserved. +// Copyright © 2017-2023 Arm Ltd. All rights reserved. // SPDX-License-Identifier: MIT // diff --git a/src/backends/backendsCommon/test/layerTests/ReverseV2TestImpl.cpp b/src/backends/backendsCommon/test/layerTests/ReverseV2TestImpl.cpp index f2774037bd..144bf9e8e1 100644 --- a/src/backends/backendsCommon/test/layerTests/ReverseV2TestImpl.cpp +++ b/src/backends/backendsCommon/test/layerTests/ReverseV2TestImpl.cpp @@ -18,73 +18,74 @@ namespace { - template - LayerTestResult ReverseV2TestImpl( - armnn::IWorkloadFactory& workloadFactory, - const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, - const armnn::ITensorHandleFactory& tensorHandleFactory, - const std::vector& input, - const std::vector& axis, - const std::vector& outputExpected, - const armnn::TensorInfo& inputInfo, - const armnn::TensorInfo& axisInfo, - const armnn::TensorInfo& outputInfo) +template +LayerTestResult ReverseV2TestImpl( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + const armnn::ITensorHandleFactory& tensorHandleFactory, + const std::vector& input, + const std::vector& axis, + const std::vector& outputExpected, + const armnn::TensorInfo& inputInfo, + const armnn::TensorInfo& axisInfo, + const armnn::TensorInfo& outputInfo) +{ + LayerTestResult result(outputInfo); + std::vector outputActual(outputInfo.GetNumElements()); + + std::unique_ptr inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo); + std::unique_ptr axisHandle = tensorHandleFactory.CreateTensorHandle(axisInfo); + std::unique_ptr outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo); + + armnn::ReverseV2QueueDescriptor queueDescriptor; + armnn::WorkloadInfo workloadInfo; + + AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get()); + AddInputToWorkload(queueDescriptor, workloadInfo, axisInfo, axisHandle.get()); + AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get()); + + // Don't execute if ReverseV2 is not supported, as an exception will be raised. + const armnn::BackendId& backend = workloadFactory.GetBackendId(); + std::string reasonIfUnsupported; + armnn::LayerSupportHandle handle = armnn::GetILayerSupportByBackendId(backend); + result.m_Supported = handle.IsReverseV2Supported(inputInfo, + axisInfo, + outputInfo, + reasonIfUnsupported); + if (!result.m_Supported) + { + return result; + } + + auto workload = workloadFactory.CreateWorkload(armnn::LayerType::ReverseV2, queueDescriptor, workloadInfo); + + inputHandle->Allocate(); + axisHandle->Allocate(); + outputHandle->Allocate(); + + if (input.data() != nullptr) + { + CopyDataToITensorHandle(inputHandle.get(), input.data()); + } + if (axis.data() != nullptr) + { + CopyDataToITensorHandle(axisHandle.get(), axis.data()); + } + + workload->PostAllocationConfigure(); + ExecuteWorkload(*workload, memoryManager); + + if (outputActual.data() != nullptr) { - LayerTestResult result(outputInfo); - std::vector outputActual(outputInfo.GetNumElements()); - - std::unique_ptr inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo); - std::unique_ptr axisHandle = tensorHandleFactory.CreateTensorHandle(axisInfo); - std::unique_ptr outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo); - - armnn::ReverseV2QueueDescriptor queueDescriptor; - armnn::WorkloadInfo workloadInfo; - - AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get()); - AddInputToWorkload(queueDescriptor, workloadInfo, axisInfo, axisHandle.get()); - AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get()); - - // Don't execute if ReverseV2 is not supported, as an exception will be raised. - const armnn::BackendId& backend = workloadFactory.GetBackendId(); - std::string reasonIfUnsupported; - armnn::LayerSupportHandle handle = armnn::GetILayerSupportByBackendId(backend); - result.m_Supported = handle.IsReverseV2Supported(inputInfo, - axisInfo, - outputInfo, - reasonIfUnsupported); - if (!result.m_Supported) - { - return result; - } - - auto workload = workloadFactory.CreateWorkload(armnn::LayerType::ReverseV2, queueDescriptor, workloadInfo); - - inputHandle->Allocate(); - axisHandle->Allocate(); - outputHandle->Allocate(); - - if (input.data() != nullptr) - { - CopyDataToITensorHandle(inputHandle.get(), input.data()); - } - if (axis.data() != nullptr) - { - CopyDataToITensorHandle(axisHandle.get(), axis.data()); - } - - workload->PostAllocationConfigure(); - ExecuteWorkload(*workload, memoryManager); - - if (outputActual.data() != nullptr) - { - CopyDataFromITensorHandle(outputActual.data(), outputHandle.get()); - } - - return LayerTestResult(outputActual, - outputExpected, - outputHandle->GetShape(), - outputInfo.GetShape()); + CopyDataFromITensorHandle(outputActual.data(), outputHandle.get()); } + + return LayerTestResult(outputActual, + outputExpected, + outputHandle->GetShape(), + outputInfo.GetShape()); + +} } template @@ -107,7 +108,7 @@ LayerTestResult ReverseV2SimpleTestEmptyAxis( 3, 4 }, qScale, qOffset); - std::vector axis = armnnUtils::QuantizedVector({1, 1}, qScale, qOffset); + std::vector axis = armnnUtils::QuantizedVector({}, qScale, qOffset); std::vector outputExpected = armnnUtils::QuantizedVector({ 1, 2, @@ -115,14 +116,14 @@ LayerTestResult ReverseV2SimpleTestEmptyAxis( }, qScale, qOffset); return ReverseV2TestImpl(workloadFactory, - memoryManager, - tensorHandleFactory, - input, - axis, - outputExpected, - inputInfo, - axisInfo, - outputInfo); + memoryManager, + tensorHandleFactory, + input, + axis, + outputExpected, + inputInfo, + axisInfo, + outputInfo); } template diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp index 1acaba0384..bfe4f6e9fd 100644 --- a/src/backends/cl/ClLayerSupport.cpp +++ b/src/backends/cl/ClLayerSupport.cpp @@ -70,6 +70,7 @@ #include "workloads/ClReduceWorkload.hpp" #include "workloads/ClReshapeWorkload.hpp" #include "workloads/ClResizeWorkload.hpp" +#include "workloads/ClReverseV2Workload.hpp" #include "workloads/ClRsqrtWorkload.hpp" #include "workloads/ClSinWorkload.hpp" #include "workloads/ClSliceWorkload.hpp" @@ -571,6 +572,11 @@ bool ClLayerSupport::IsLayerSupported(const LayerType& type, infos[1], *(PolymorphicDowncast(&descriptor)), reasonIfUnsupported); + case LayerType::ReverseV2: + return IsReverseV2Supported(infos[0], + infos[1], + infos[2], + reasonIfUnsupported); case LayerType::Shape: return LayerSupportBase::IsShapeSupported(infos[0], infos[1], @@ -1423,6 +1429,18 @@ bool ClLayerSupport::IsResizeSupported(const TensorInfo& input, FORWARD_WORKLOAD_VALIDATE_FUNC(ClResizeWorkloadValidate, reasonIfUnsupported, input, output, descriptor); } +bool ClLayerSupport::IsReverseV2Supported(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output, + Optional reasonIfUnsupported) const +{ + FORWARD_WORKLOAD_VALIDATE_FUNC(ClReverseV2WorkloadValidate, + reasonIfUnsupported, + input, + axis, + output); +} + bool ClLayerSupport::IsSliceSupported(const TensorInfo& input, const TensorInfo& output, const SliceDescriptor& descriptor, diff --git a/src/backends/cl/ClLayerSupport.hpp b/src/backends/cl/ClLayerSupport.hpp index 9a8f896cab..907db01b89 100644 --- a/src/backends/cl/ClLayerSupport.hpp +++ b/src/backends/cl/ClLayerSupport.hpp @@ -295,6 +295,11 @@ public: const ResizeDescriptor& descriptor, Optional reasonIfUnsupported = EmptyOptional()) const; + bool IsReverseV2Supported(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output, + Optional reasonIfUnsupported) const; + bool IsSliceSupported(const TensorInfo& input, const TensorInfo& output, const SliceDescriptor& descriptor, diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp index da05f67711..6fe42644c2 100644 --- a/src/backends/cl/ClWorkloadFactory.cpp +++ b/src/backends/cl/ClWorkloadFactory.cpp @@ -711,6 +711,11 @@ std::unique_ptr ClWorkloadFactory::CreateWorkload(LayerType type, auto resizeQueueDescriptor = PolymorphicDowncast(&descriptor); return MakeWorkload(*resizeQueueDescriptor, info, m_CLCompileContext); } + case LayerType::ReverseV2: + { + auto reverseV2QueueDescriptor = PolymorphicDowncast(&descriptor); + return MakeWorkload(*reverseV2QueueDescriptor, info, m_CLCompileContext); + } case LayerType::Slice : { auto sliceQueueDescriptor = PolymorphicDowncast(&descriptor); diff --git a/src/backends/cl/backend.mk b/src/backends/cl/backend.mk index 34993059c2..2143c30309 100644 --- a/src/backends/cl/backend.mk +++ b/src/backends/cl/backend.mk @@ -79,6 +79,7 @@ BACKEND_SOURCES := \ workloads/ClReduceWorkload.cpp \ workloads/ClReshapeWorkload.cpp \ workloads/ClResizeWorkload.cpp \ + workloads/ClReverseV2Workload.cpp \ workloads/ClRsqrtWorkload.cpp \ workloads/ClSinWorkload.cpp \ workloads/ClSliceWorkload.cpp \ diff --git a/src/backends/cl/test/ClEndToEndTests.cpp b/src/backends/cl/test/ClEndToEndTests.cpp index 50ba1dbb99..2436a8223f 100644 --- a/src/backends/cl/test/ClEndToEndTests.cpp +++ b/src/backends/cl/test/ClEndToEndTests.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -345,6 +346,12 @@ TEST_CASE("ClReshapeEndToEndTestFloat16") ReshapeEndToEndFloat16(clDefaultBackends); } +// ReverseV2 +TEST_CASE("ClReverseV2EndToEndTest") +{ + ReverseV2EndToEnd(clDefaultBackends); +} + // Space to depth TEST_CASE("ClSpaceToDepthNhwcEndToEndTest1") { diff --git a/src/backends/cl/test/ClLayerTests.cpp b/src/backends/cl/test/ClLayerTests.cpp index a596a01be8..da2b967fcb 100644 --- a/src/backends/cl/test/ClLayerTests.cpp +++ b/src/backends/cl/test/ClLayerTests.cpp @@ -2015,6 +2015,35 @@ ARMNN_AUTO_TEST_FIXTURE_WITH_THF(AlignCornersResizeNearestNeighbourUint8Nhwc, AlignCornersResizeNearestNeighbourTest, DataLayout::NHWC) +// ReverseV2 +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple1DimFloat32, ReverseV2SimpleTest1Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim1AxisFloat32, ReverseV2SimpleTest2Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisFloat32, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple3Dim1AxisFloat32, ReverseV2SimpleTest3Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple3Dim2AxisFloat32, ReverseV2SimpleTest3Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple3Dim3AxisFloat32, ReverseV2SimpleTest3Dim3Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim1AxisFloat32, ReverseV2SimpleTest4Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim2AxisFloat32, ReverseV2SimpleTest4Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim3AxisFloat32, ReverseV2SimpleTest4Dim3Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim4AxisFloat32, ReverseV2SimpleTest4Dim4Axis) + +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowOddCol2DimFloat32, ReverseV2EvenRowOddColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowOddCol3DimFloat32, ReverseV2EvenRowOddColTest3Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowEvenCol2DimFloat32, ReverseV2EvenRowEvenColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowEvenCol3DimFloat32, ReverseV2EvenRowEvenColTest3Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowOddCol2DimFloat32, ReverseV2OddRowOddColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowOddCol3DimFloat32, ReverseV2OddRowOddColTest3Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowEvenCol2DimFloat32, ReverseV2OddRowEvenColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowEvenCol3DimFloat32, ReverseV2OddRowEvenColTest3Dim) + +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2NegAxis2Dim1AxisFloat32, ReverseV2NegAxisTest2Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2NegAxis3Dim2AxisFloat32, ReverseV2NegAxisTest3Dim2Axis) + +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisFloat16, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisQAsymmS8, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisQAsymmU8, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisQSymmS16, ReverseV2SimpleTest2Dim2Axis) + // Rsqrt ARMNN_AUTO_TEST_FIXTURE_WITH_THF(Rsqrt2d, ClContextControlFixture, Rsqrt2dTest) ARMNN_AUTO_TEST_FIXTURE_WITH_THF(Rsqrt3d, ClContextControlFixture, Rsqrt3dTest) diff --git a/src/backends/cl/workloads/CMakeLists.txt b/src/backends/cl/workloads/CMakeLists.txt index cb16ab19e8..f38366fa57 100644 --- a/src/backends/cl/workloads/CMakeLists.txt +++ b/src/backends/cl/workloads/CMakeLists.txt @@ -109,6 +109,8 @@ list(APPEND armnnClBackendWorkloads_sources ClReshapeWorkload.hpp ClResizeWorkload.cpp ClResizeWorkload.hpp + ClReverseV2Workload.cpp + ClReverseV2Workload.hpp ClRsqrtWorkload.cpp ClRsqrtWorkload.hpp ClSinWorkload.cpp diff --git a/src/backends/cl/workloads/ClReverseV2Workload.cpp b/src/backends/cl/workloads/ClReverseV2Workload.cpp new file mode 100644 index 0000000000..8802d33633 --- /dev/null +++ b/src/backends/cl/workloads/ClReverseV2Workload.cpp @@ -0,0 +1,50 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "ClReverseV2Workload.hpp" +#include "ClWorkloadUtils.hpp" +#include +#include +#include + +using namespace armnn::armcomputetensorutils; + +namespace armnn +{ +arm_compute::Status ClReverseV2WorkloadValidate(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output) +{ + const arm_compute::TensorInfo aclInput = BuildArmComputeTensorInfo(input); + const arm_compute::TensorInfo aclAxis = BuildArmComputeTensorInfo(axis); + const arm_compute::TensorInfo aclOutput = BuildArmComputeTensorInfo(output); + + return arm_compute::CLReverse::validate(&aclInput, &aclOutput, &aclAxis, true); +} + +ClReverseV2Workload::ClReverseV2Workload(const armnn::ReverseV2QueueDescriptor &descriptor, + const armnn::WorkloadInfo &info, + const arm_compute::CLCompileContext& clCompileContext) + : BaseWorkload(descriptor, info) +{ + m_Data.ValidateInputsOutputs("ClReverseV2Workload", 2, 1); + + arm_compute::ICLTensor& input = static_cast(m_Data.m_Inputs[0])->GetTensor(); + arm_compute::ICLTensor& axis = static_cast(m_Data.m_Inputs[1])->GetTensor(); + arm_compute::ICLTensor& output = static_cast(m_Data.m_Outputs[0])->GetTensor(); + + { + ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID("ClReverseV2Workload_configure"); + m_Layer.configure(clCompileContext, &input, &output, &axis, true); + } +} + +void ClReverseV2Workload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID("ClReverseV2Workload_Execute"); + m_Layer.run(); +} + +} //namespace armnn \ No newline at end of file diff --git a/src/backends/cl/workloads/ClReverseV2Workload.hpp b/src/backends/cl/workloads/ClReverseV2Workload.hpp new file mode 100644 index 0000000000..60d4a500e0 --- /dev/null +++ b/src/backends/cl/workloads/ClReverseV2Workload.hpp @@ -0,0 +1,33 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "ClBaseWorkload.hpp" + +#include +#include +#include "arm_compute/runtime/CL/CLTensor.h" + +namespace armnn +{ +arm_compute::Status ClReverseV2WorkloadValidate(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output); + +class ClReverseV2Workload : public BaseWorkload +{ +public: + ClReverseV2Workload(const ReverseV2QueueDescriptor &descriptor, + const WorkloadInfo &info, + const arm_compute::CLCompileContext& clCompileContext); + + void Execute() const override; + +private: + mutable arm_compute::CLReverse m_Layer; +}; + +} //namespace armnn \ No newline at end of file diff --git a/src/backends/cl/workloads/ClWorkloads.hpp b/src/backends/cl/workloads/ClWorkloads.hpp index cec8706911..40b3e99258 100644 --- a/src/backends/cl/workloads/ClWorkloads.hpp +++ b/src/backends/cl/workloads/ClWorkloads.hpp @@ -55,6 +55,7 @@ #include "ClReduceWorkload.hpp" #include "ClReshapeWorkload.hpp" #include "ClResizeWorkload.hpp" +#include "ClReverseV2Workload.hpp" #include "ClRsqrtWorkload.hpp" #include "ClSinWorkload.hpp" #include "ClSliceWorkload.hpp" diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp index ef1d21835a..4be5b7cb4e 100644 --- a/src/backends/neon/NeonLayerSupport.cpp +++ b/src/backends/neon/NeonLayerSupport.cpp @@ -69,6 +69,7 @@ #include "workloads/NeonReduceWorkload.hpp" #include "workloads/NeonReshapeWorkload.hpp" #include "workloads/NeonResizeWorkload.hpp" +#include "workloads/NeonReverseV2Workload.hpp" #include "workloads/NeonRsqrtWorkload.hpp" #include "workloads/NeonSinWorkload.hpp" #include "workloads/NeonSliceWorkload.hpp" @@ -582,6 +583,11 @@ bool IsLayerTypeSupported(const LayerType& type, infos[1], *(PolymorphicDowncast(&descriptor)), reasonIfUnsupported); + case LayerType::ReverseV2: + return support.IsReverseV2Supported(infos[0], + infos[1], + infos[2], + reasonIfUnsupported); case LayerType::Shape: return support.IsShapeSupported(infos[0], infos[1], @@ -1515,6 +1521,18 @@ bool NeonLayerSupport::IsResizeSupported(const TensorInfo& input, descriptor); } +bool NeonLayerSupport::IsReverseV2Supported(const armnn::TensorInfo &input, + const armnn::TensorInfo &axis, + const armnn::TensorInfo &output, + Optional reasonIfUnsupported) const +{ + FORWARD_WORKLOAD_VALIDATE_FUNC(NeonReverseV2WorkloadValidate, + reasonIfUnsupported, + input, + axis, + output); +} + bool NeonLayerSupport::IsSliceSupported(const TensorInfo& input, const TensorInfo& output, const SliceDescriptor& descriptor, diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp index 0295c2b3e2..8372df3e08 100644 --- a/src/backends/neon/NeonLayerSupport.hpp +++ b/src/backends/neon/NeonLayerSupport.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2017 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once @@ -295,6 +295,11 @@ public: const ResizeDescriptor& descriptor, Optional reasonIfUnsupported = EmptyOptional()) const; + bool IsReverseV2Supported(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output, + Optional reasonIfUnsupported) const; + bool IsSliceSupported(const TensorInfo& input, const TensorInfo& output, const SliceDescriptor& descriptor, diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index 4f131ac575..9b74f750f9 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -572,6 +572,11 @@ std::unique_ptr NeonWorkloadFactory::CreateWorkload(LayerType type, auto resizeQueueDescriptor = PolymorphicDowncast(&descriptor); return std::make_unique(*resizeQueueDescriptor, info); } + case LayerType::ReverseV2 : + { + auto reverseV2QueueDescriptor = PolymorphicDowncast(&descriptor); + return std::make_unique(*reverseV2QueueDescriptor, info); + } case LayerType::Slice : { auto sliceQueueDescriptor = PolymorphicDowncast(&descriptor); diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk index 3961ed1e34..3ab07a9431 100644 --- a/src/backends/neon/backend.mk +++ b/src/backends/neon/backend.mk @@ -77,6 +77,7 @@ BACKEND_SOURCES := \ workloads/NeonReduceWorkload.cpp \ workloads/NeonReshapeWorkload.cpp \ workloads/NeonResizeWorkload.cpp \ + workloads/NeonReverseV2Workload.cpp \ workloads/NeonRsqrtWorkload.cpp \ workloads/NeonSinWorkload.cpp \ workloads/NeonSliceWorkload.cpp \ diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp index e582fadf11..1e2636bf6f 100644 --- a/src/backends/neon/test/NeonEndToEndTests.cpp +++ b/src/backends/neon/test/NeonEndToEndTests.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -671,6 +672,12 @@ TEST_CASE("NeonReshapeEndToEndTestFloat16") ReshapeEndToEndFloat16(neonDefaultBackends); } +// ReverseV2 +TEST_CASE("NeonReverseV2EndToEndTest") +{ + ReverseV2EndToEnd(neonDefaultBackends); +} + // Slice TEST_CASE("NeonSliceEndtoEndTestFloat32") { diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp index a938ceb9c3..9db6d2c2e6 100644 --- a/src/backends/neon/test/NeonLayerTests.cpp +++ b/src/backends/neon/test/NeonLayerTests.cpp @@ -1352,6 +1352,36 @@ ARMNN_AUTO_TEST_CASE_WITH_THF(AlignCornersResizeNearestNeighbourUint8Nhwc, AlignCornersResizeNearestNeighbourTest, DataLayout::NHWC) +// ReverseV2 +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2SimpleEmptyAxisFloat32, ReverseV2SimpleTestEmptyAxis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple1DimFloat32, ReverseV2SimpleTest1Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim1AxisFloat32, ReverseV2SimpleTest2Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisFloat32, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple3Dim1AxisFloat32, ReverseV2SimpleTest3Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple3Dim2AxisFloat32, ReverseV2SimpleTest3Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple3Dim3AxisFloat32, ReverseV2SimpleTest3Dim3Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim1AxisFloat32, ReverseV2SimpleTest4Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim2AxisFloat32, ReverseV2SimpleTest4Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim3AxisFloat32, ReverseV2SimpleTest4Dim3Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple4Dim4AxisFloat32, ReverseV2SimpleTest4Dim4Axis) + +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowOddCol2DimFloat32, ReverseV2EvenRowOddColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowOddCol3DimFloat32, ReverseV2EvenRowOddColTest3Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowEvenCol2DimFloat32, ReverseV2EvenRowEvenColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2EvenRowEvenCol3DimFloat32, ReverseV2EvenRowEvenColTest3Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowOddCol2DimFloat32, ReverseV2OddRowOddColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowOddCol3DimFloat32, ReverseV2OddRowOddColTest3Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowEvenCol2DimFloat32, ReverseV2OddRowEvenColTest2Dim) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2OddRowEvenCol3DimFloat32, ReverseV2OddRowEvenColTest3Dim) + +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2NegAxis2Dim1AxisFloat32, ReverseV2NegAxisTest2Dim1Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2NegAxis3Dim2AxisFloat32, ReverseV2NegAxisTest3Dim2Axis) + +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisFloat16, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisQAsymmS8, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisQAsymmU8, ReverseV2SimpleTest2Dim2Axis) +ARMNN_AUTO_TEST_CASE_WITH_THF(ReverseV2Simple2Dim2AxisQSymmS16, ReverseV2SimpleTest2Dim2Axis) + // Slice ARMNN_AUTO_TEST_CASE(Slice4dFloat32, Slice4dFloat32Test) ARMNN_AUTO_TEST_CASE(Slice3dFloat32, Slice3dFloat32Test) diff --git a/src/backends/neon/workloads/CMakeLists.txt b/src/backends/neon/workloads/CMakeLists.txt index f4438e4baa..357fdcdf91 100644 --- a/src/backends/neon/workloads/CMakeLists.txt +++ b/src/backends/neon/workloads/CMakeLists.txt @@ -113,6 +113,8 @@ list(APPEND armnnNeonBackendWorkloads_sources NeonReshapeWorkload.hpp NeonResizeWorkload.cpp NeonResizeWorkload.hpp + NeonReverseV2Workload.cpp + NeonReverseV2Workload.hpp NeonRsqrtWorkload.cpp NeonRsqrtWorkload.hpp NeonSinWorkload.cpp diff --git a/src/backends/neon/workloads/NeonReverseV2Workload.cpp b/src/backends/neon/workloads/NeonReverseV2Workload.cpp new file mode 100644 index 0000000000..c7d9fa1245 --- /dev/null +++ b/src/backends/neon/workloads/NeonReverseV2Workload.cpp @@ -0,0 +1,44 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "NeonReverseV2Workload.hpp" +#include "NeonWorkloadUtils.hpp" +#include +#include +#include + +namespace armnn +{ +arm_compute::Status NeonReverseV2WorkloadValidate(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output) +{ + const arm_compute::TensorInfo aclInput = BuildArmComputeTensorInfo(input); + const arm_compute::TensorInfo aclAxis = BuildArmComputeTensorInfo(axis); + const arm_compute::TensorInfo aclOutput = BuildArmComputeTensorInfo(output); + + return arm_compute::NEReverse::validate(&aclInput, &aclOutput, &aclAxis, true); +} + +NeonReverseV2Workload::NeonReverseV2Workload(const ReverseV2QueueDescriptor& descriptor, + const WorkloadInfo& info) + : BaseWorkload(descriptor, info) +{ + m_Data.ValidateInputsOutputs("NeonReverseV2Workload", 2, 1); + + arm_compute::ITensor& input = PolymorphicDowncast(m_Data.m_Inputs[0])->GetTensor(); + arm_compute::ITensor& axis = PolymorphicDowncast(m_Data.m_Inputs[1])->GetTensor(); + arm_compute::ITensor& output = PolymorphicDowncast(m_Data.m_Outputs[0])->GetTensor(); + + m_Layer.configure(&input, &output, &axis, true); +} + +void NeonReverseV2Workload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID("NeonReverseV2Workload_Execute"); + m_Layer.run(); +} + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/neon/workloads/NeonReverseV2Workload.hpp b/src/backends/neon/workloads/NeonReverseV2Workload.hpp new file mode 100644 index 0000000000..fa6a71d392 --- /dev/null +++ b/src/backends/neon/workloads/NeonReverseV2Workload.hpp @@ -0,0 +1,29 @@ +// +// Copyright © 2023 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "NeonBaseWorkload.hpp" + +#include +#include + +namespace armnn +{ +arm_compute::Status NeonReverseV2WorkloadValidate(const TensorInfo& input, + const TensorInfo& axis, + const TensorInfo& output); + +class NeonReverseV2Workload : public BaseWorkload +{ +public: + NeonReverseV2Workload(const ReverseV2QueueDescriptor& descriptor, const WorkloadInfo& info); + void Execute() const override; + +private: + mutable arm_compute::NEReverse m_Layer; +}; + +} // namespace armnn \ No newline at end of file diff --git a/src/backends/neon/workloads/NeonWorkloads.hpp b/src/backends/neon/workloads/NeonWorkloads.hpp index 615e5d87c8..c14b9b44af 100644 --- a/src/backends/neon/workloads/NeonWorkloads.hpp +++ b/src/backends/neon/workloads/NeonWorkloads.hpp @@ -59,6 +59,7 @@ #include "NeonReduceWorkload.hpp" #include "NeonReshapeWorkload.hpp" #include "NeonResizeWorkload.hpp" +#include "NeonReverseV2Workload.hpp" #include "NeonRsqrtWorkload.hpp" #include "NeonSinWorkload.hpp" #include "NeonSliceWorkload.hpp" diff --git a/src/backends/reference/workloads/RefReverseV2Workload.cpp b/src/backends/reference/workloads/RefReverseV2Workload.cpp index b0d2f445b5..192de7e455 100644 --- a/src/backends/reference/workloads/RefReverseV2Workload.cpp +++ b/src/backends/reference/workloads/RefReverseV2Workload.cpp @@ -38,7 +38,7 @@ namespace armnn inputs[0]->Map()); std::unique_ptr> axisDecoder = MakeDecoder(GetTensorInfo(inputs[1]), - inputs[1]->Map()); + inputs[1]->Map()); std::unique_ptr> outputEncoder = MakeEncoder(GetTensorInfo(outputs[0]), outputs[0]->Map()); -- cgit v1.2.1