IVGCVSW-6936 Add SQRT support to Neon

Signed-off-by: Teresa Charlin <teresa.charlinreyes@arm.com>
Change-Id: I195957541069cb52cdd2c8aead0e4a34498a6f38
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp
index 26b650b..d50b253 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -72,6 +72,7 @@
 #include "workloads/NeonSpaceToBatchNdWorkload.hpp"
 #include "workloads/NeonSpaceToDepthWorkload.hpp"
 #include "workloads/NeonSplitterWorkload.hpp"
+#include "workloads/NeonSqrtWorkload.hpp"
 #include "workloads/NeonStackWorkload.hpp"
 #include "workloads/NeonStridedSliceWorkload.hpp"
 #include "workloads/NeonSubtractionWorkload.hpp"
@@ -941,6 +942,11 @@
                                            reasonIfUnsupported,
                                            input,
                                            output);
+        case UnaryOperation::Sqrt:
+            FORWARD_WORKLOAD_VALIDATE_FUNC(NeonSqrtWorkloadValidate,
+                                           reasonIfUnsupported,
+                                           input,
+                                           output);
         default:
             return false;
     }
diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk
index c522df6..d940c92 100644
--- a/src/backends/neon/backend.mk
+++ b/src/backends/neon/backend.mk
@@ -81,6 +81,7 @@
         workloads/NeonSpaceToBatchNdWorkload.cpp \
         workloads/NeonSpaceToDepthWorkload.cpp \
         workloads/NeonSplitterWorkload.cpp \
+        workloads/NeonSqrtWorkload.cpp \
         workloads/NeonStackWorkload.cpp \
         workloads/NeonStridedSliceWorkload.cpp \
         workloads/NeonSubtractionWorkload.cpp \
diff --git a/src/backends/neon/workloads/CMakeLists.txt b/src/backends/neon/workloads/CMakeLists.txt
index 8953dc9..16fae69 100644
--- a/src/backends/neon/workloads/CMakeLists.txt
+++ b/src/backends/neon/workloads/CMakeLists.txt
@@ -123,6 +123,8 @@
     NeonSpaceToDepthWorkload.hpp
     NeonSplitterWorkload.cpp
     NeonSplitterWorkload.hpp
+    NeonSqrtWorkload.cpp
+    NeonSqrtWorkload.hpp
     NeonStackWorkload.cpp
     NeonStackWorkload.hpp
     NeonStridedSliceWorkload.cpp
diff --git a/src/backends/neon/workloads/NeonSqrtWorkload.cpp b/src/backends/neon/workloads/NeonSqrtWorkload.cpp
new file mode 100644
index 0000000..dc6e3a3
--- /dev/null
+++ b/src/backends/neon/workloads/NeonSqrtWorkload.cpp
@@ -0,0 +1,60 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "NeonSqrtWorkload.hpp"
+
+#include "NeonWorkloadUtils.hpp"
+
+#include <aclCommon/ArmComputeTensorHandle.hpp>
+#include <aclCommon/ArmComputeTensorUtils.hpp>
+#include <aclCommon/ArmComputeUtils.hpp>
+#include <armnn/utility/PolymorphicDowncast.hpp>
+
+namespace armnn
+{
+
+arm_compute::Status NeonSqrtWorkloadValidate(const TensorInfo& input, const TensorInfo& output)
+{
+    const arm_compute::TensorInfo aclInput  = armcomputetensorutils::BuildArmComputeTensorInfo(input);
+    const arm_compute::TensorInfo aclOutput = armcomputetensorutils::BuildArmComputeTensorInfo(output);
+
+    ActivationDescriptor descriptor;
+    descriptor.m_Function = ActivationFunction::Sqrt;
+    const arm_compute::ActivationLayerInfo activationLayerInfo =
+            ConvertActivationDescriptorToAclActivationLayerInfo(descriptor);
+
+    return arm_compute::NEActivationLayer::validate(&aclInput, &aclOutput, activationLayerInfo);
+}
+
+NeonSqrtWorkload::NeonSqrtWorkload(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info)
+    : NeonBaseWorkload<ElementwiseUnaryQueueDescriptor>(descriptor, info)
+{
+    ARMNN_ASSERT(descriptor.m_Parameters.m_Operation == UnaryOperation::Sqrt);
+
+    ARMNN_REPORT_PROFILING_WORKLOAD_DESC("NeonSqrtWorkload_Construct",
+                                         descriptor.m_Parameters,
+                                         info,
+                                         this->GetGuid());
+
+    m_Data.ValidateInputsOutputs("NeonSqrtWorkload", 1, 1);
+
+    ActivationDescriptor activationDescriptor;
+    activationDescriptor.m_Function = ActivationFunction::Sqrt;
+    const arm_compute::ActivationLayerInfo activationLayerInfo =
+            ConvertActivationDescriptorToAclActivationLayerInfo(activationDescriptor);
+
+    arm_compute::ITensor& input  = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
+    arm_compute::ITensor& output = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
+
+    m_SqrtLayer.configure(&input, &output, activationLayerInfo);
+}
+
+void NeonSqrtWorkload::Execute() const
+{
+    ARMNN_SCOPED_PROFILING_EVENT_NEON_GUID("NeonSqrtWorkload_Execute", this->GetGuid());
+    m_SqrtLayer.run();
+}
+
+} // namespace armnn
\ No newline at end of file
diff --git a/src/backends/neon/workloads/NeonSqrtWorkload.hpp b/src/backends/neon/workloads/NeonSqrtWorkload.hpp
new file mode 100644
index 0000000..4792558
--- /dev/null
+++ b/src/backends/neon/workloads/NeonSqrtWorkload.hpp
@@ -0,0 +1,27 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include "NeonBaseWorkload.hpp"
+#include <arm_compute/core/Error.h>
+#include <arm_compute/runtime/NEON/functions/NEActivationLayer.h>
+
+namespace armnn
+{
+
+arm_compute::Status NeonSqrtWorkloadValidate(const TensorInfo& input, const TensorInfo& output);
+
+class NeonSqrtWorkload : public NeonBaseWorkload<ElementwiseUnaryQueueDescriptor>
+{
+public:
+    NeonSqrtWorkload(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info);
+    virtual void Execute() const override;
+
+private:
+    mutable arm_compute::NEActivationLayer m_SqrtLayer;
+};
+
+} //namespace armnn
\ No newline at end of file