IVGCVSW-6262 Add support for Reduce Prod

* Tflite parser
* Tflite delegate
* Serializer
* Deserializer
* Ref, CpuAcc and GpuAcc workloads

Signed-off-by: Teresa Charlin <teresa.charlinreyes@arm.com>
Change-Id: I601a9ee1680b372c7955d9a628857d08c3cfd377
diff --git a/delegate/src/Reduce.hpp b/delegate/src/Reduce.hpp
index 13a11d3..bcea16f 100644
--- a/delegate/src/Reduce.hpp
+++ b/delegate/src/Reduce.hpp
@@ -91,6 +91,10 @@
     {
         desc.m_ReduceOperation = armnn::ReduceOperation::Sum;
     }
+    else if (reduceOperatorCode == kTfLiteBuiltinReduceProd)
+    {
+        desc.m_ReduceOperation = armnn::ReduceOperation::Prod;
+    }
     else
     {
         TF_LITE_MAYBE_KERNEL_LOG(
diff --git a/delegate/src/armnn_delegate.cpp b/delegate/src/armnn_delegate.cpp
index d3ccecb..f13bb57 100644
--- a/delegate/src/armnn_delegate.cpp
+++ b/delegate/src/armnn_delegate.cpp
@@ -765,6 +765,12 @@
                                        tfLiteNode,
                                        nodeIndex,
                                        kTfLiteBuiltinReduceMin);
+        case kTfLiteBuiltinReduceProd:
+            return VisitReduceOperator(delegateData,
+                                       tfLiteContext,
+                                       tfLiteNode,
+                                       nodeIndex,
+                                       kTfLiteBuiltinReduceProd);
         case kTfLiteBuiltinRelu:
             return VisitActivationOperator(delegateData,
                                            tfLiteContext,
diff --git a/delegate/src/test/ReduceTest.cpp b/delegate/src/test/ReduceTest.cpp
index 49608b6..5dd3356 100644
--- a/delegate/src/test/ReduceTest.cpp
+++ b/delegate/src/test/ReduceTest.cpp
@@ -350,5 +350,74 @@
 
 } // End of Sum_GpuAccTests
 
+// PROD Tests
+TEST_SUITE("Prod_CpuRefTests")
+{
+
+TEST_CASE ("Prod_Uint8_KeepDims_CpuRef_Test")
+{
+    std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
+    std::vector<uint8_t> expectedOutputValues { 4, 6, 3 };
+    ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_PROD,
+                            backends,
+                            expectedOutputValues);
+}
+
+TEST_CASE ("Prod_Fp32_CpuRef_Test")
+{
+    std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
+    std::vector<float>   expectedOutputValues { 10010.0f, 11022.0f, 12036.0f };
+    ReduceFp32Test(tflite::BuiltinOperator_REDUCE_PROD,
+                   backends,
+                   expectedOutputValues);
+}
+
+} // End of Prod_CpuRefTests
+
+TEST_SUITE("Prod_CpuAccTests")
+{
+
+TEST_CASE ("Prod_Uint8_KeepDims_CpuAcc_Test")
+{
+    std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc};
+    std::vector<uint8_t> expectedOutputValues { 4, 6, 3 };
+    ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_PROD,
+                            backends,
+                            expectedOutputValues);
+}
+
+TEST_CASE ("Prod_Fp32_CpuAcc_Test")
+{
+    std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc};
+    std::vector<float>   expectedOutputValues { 10010.0f, 11022.0f, 12036.0f };
+    ReduceFp32Test(tflite::BuiltinOperator_REDUCE_PROD,
+                   backends,
+                   expectedOutputValues);
+}
+
+} // End of Prod_CpuAccTests
+
+TEST_SUITE("Prod_GpuAccTests")
+{
+
+TEST_CASE ("Prod_Uint8_KeepDims_GpuAcc_Test")
+{
+    std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
+    std::vector<uint8_t> expectedOutputValues { 4, 6, 3 };
+    ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_PROD,
+                            backends,
+                            expectedOutputValues);
+}
+
+TEST_CASE ("Prod_Fp32_GpuAcc_Test")
+{
+    std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
+    std::vector<float>   expectedOutputValues { 10010.0f, 11022.0f, 12036.0f };
+    ReduceFp32Test(tflite::BuiltinOperator_REDUCE_PROD,
+                   backends,
+                   expectedOutputValues);
+}
+
+} // End of Prod_GpuAccTests
 
 } // namespace armnnDelegate
\ No newline at end of file