IVGCVSW-7572 Only print JSON profiling once per ArmnnSubgraph.

Previously the JSON profiling was printed once per delegate invoke call.
Modify that to print only once per ArmnnSubgraph. Data from multiple
inferences is grouped together.

Signed-off-by: Colm Donelan <colm.donelan@arm.com>
Change-Id: I1beb60eae4685c8e628dd1939f41bd649fc2a6ba
diff --git a/delegate/classic/include/armnn_delegate.hpp b/delegate/classic/include/armnn_delegate.hpp
index e94a6e2..a6957dc 100644
--- a/delegate/classic/include/armnn_delegate.hpp
+++ b/delegate/classic/include/armnn_delegate.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2020-2024 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -98,6 +98,8 @@
                                  const TfLiteDelegateParams* parameters,
                                  const Delegate* delegate);
 
+    ~ArmnnSubgraph();
+
     TfLiteStatus Prepare(TfLiteContext* tfLiteContext);
 
     TfLiteStatus Invoke(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode);
diff --git a/delegate/classic/src/armnn_delegate.cpp b/delegate/classic/src/armnn_delegate.cpp
index 57488fc..05bf9b2 100644
--- a/delegate/classic/src/armnn_delegate.cpp
+++ b/delegate/classic/src/armnn_delegate.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2020-2024 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -273,6 +273,16 @@
     return DELEGATE_VERSION;
 }
 
+ArmnnSubgraph::~ArmnnSubgraph()
+{
+    // The delegate holds its own Arm NN runtime so this is our last chance to print internal profiling data.
+    std::shared_ptr<armnn::IProfiler> profiler = m_Runtime->GetProfiler(m_NetworkId);
+    if (profiler && profiler->IsProfilingEnabled())
+    {
+        profiler->Print(std::cout);
+    }
+}
+
 TfLiteStatus ArmnnSubgraph::AddInputLayer(DelegateData& delegateData,
                                           TfLiteContext* tfLiteContext,
                                           const TfLiteIntArray* inputs,
@@ -526,12 +536,6 @@
 
     // Run graph
     auto status = m_Runtime->EnqueueWorkload(m_NetworkId, inputTensors, outputTensors);
-    // The delegate holds its own Arm NN runtime so this is our last chance to print internal profiling data.
-    std::shared_ptr<armnn::IProfiler> profiler = m_Runtime->GetProfiler(m_NetworkId);
-    if (profiler && profiler->IsProfilingEnabled())
-    {
-        profiler->Print(std::cout);
-    }
     return (status == armnn::Status::Success) ? kTfLiteOk : kTfLiteError;
 }
 
diff --git a/delegate/opaque/include/armnn_delegate.hpp b/delegate/opaque/include/armnn_delegate.hpp
index ae85556..57fc9c2 100644
--- a/delegate/opaque/include/armnn_delegate.hpp
+++ b/delegate/opaque/include/armnn_delegate.hpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2023-2024 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -128,6 +128,8 @@
                                  const TfLiteOpaqueDelegateParams* parameters,
                                  const ArmnnOpaqueDelegate* delegate);
 
+    ~ArmnnSubgraph();
+
     TfLiteStatus Prepare(TfLiteOpaqueContext* tfLiteContext);
 
     TfLiteStatus Invoke(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode);
diff --git a/delegate/opaque/src/armnn_delegate.cpp b/delegate/opaque/src/armnn_delegate.cpp
index 54bdf36..4ed0a78 100644
--- a/delegate/opaque/src/armnn_delegate.cpp
+++ b/delegate/opaque/src/armnn_delegate.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2023-2024 Arm Ltd and Contributors. All rights reserved.
 // SPDX-License-Identifier: MIT
 //
 
@@ -376,6 +376,16 @@
     return nodesToDelegate;
 }
 
+ArmnnSubgraph::~ArmnnSubgraph()
+{
+    // The delegate holds its own Arm NN runtime so this is our last chance to print internal profiling data.
+    std::shared_ptr<armnn::IProfiler> profiler = m_Runtime->GetProfiler(m_NetworkId);
+    if (profiler && profiler->IsProfilingEnabled())
+    {
+        profiler->Print(std::cout);
+    }
+}
+
 TfLiteStatus ArmnnSubgraph::AddInputLayer(DelegateData& delegateData,
                                           TfLiteOpaqueContext* tfLiteContext,
                                           const TfLiteIntArray* inputs,
@@ -668,12 +678,6 @@
     try
     {
         auto status = m_Runtime->EnqueueWorkload(m_NetworkId, inputTensors, outputTensors);
-        // The delegate holds its own Arm NN runtime so this is our last chance to print internal profiling data.
-        std::shared_ptr<armnn::IProfiler> profiler = m_Runtime->GetProfiler(m_NetworkId);
-        if (profiler && profiler->IsProfilingEnabled())
-        {
-            profiler->Print(std::cout);
-        }
         return (status == armnn::Status::Success) ? kTfLiteOk : kTfLiteError;
     }
     catch (armnn::InvalidArgumentException& ex)