IVGCVSW-5619 Add OptimizerOptions and NetworkProperties to ArmNN Delegate

 * Add OptimizerOptions, NetworkProperties, DebugCallbackFunction
to DelegateOptions
 * Enable OptimizerOptions when the network is being optimized
 * Enable NetworkProperties when loading network
 * Enable DebugCallbackFunction
 * Add error message when loading network
 * Log warning instead of error when operator is not supported but
could fallback to another backend
 * Improve uint16_t CompareData
 * Unit tests

Signed-off-by: Narumol Prangnawarat <narumol.prangnawarat@arm.com>
Change-Id: I353035afb442774bfeb1c62570a90755c2ceaf38
diff --git a/delegate/src/armnn_delegate.cpp b/delegate/src/armnn_delegate.cpp
index 6250a5f..6dba890 100644
--- a/delegate/src/armnn_delegate.cpp
+++ b/delegate/src/armnn_delegate.cpp
@@ -134,6 +134,10 @@
     {
         runtimeOptions.m_BackendOptions = backendOptions;
     }
+    else if (!m_Options.GetOptimizerOptions().m_ModelOptions.empty())
+    {
+        runtimeOptions.m_BackendOptions = m_Options.GetOptimizerOptions().m_ModelOptions;
+    }
     m_Runtime = armnn::IRuntime::Create(runtimeOptions);
 
     std::vector<armnn::BackendId> backends;
@@ -288,7 +292,6 @@
 
     delegateData.m_OutputSlotForNode = std::vector<armnn::IOutputSlot*>(tfLiteContext->tensors_size, nullptr);
 
-
     std::vector<armnn::BindingPointInfo> inputBindings;
     std::vector<armnn::BindingPointInfo> outputBindings;
 
@@ -331,7 +334,8 @@
     {
         optNet = armnn::Optimize(*(delegateData.m_Network.get()),
                                  delegate->m_Options.GetBackends(),
-                                 delegate->m_Runtime->GetDeviceSpec());
+                                 delegate->m_Runtime->GetDeviceSpec(),
+                                 delegate->m_Options.GetOptimizerOptions());
     }
     catch (std::exception &ex)
     {
@@ -348,11 +352,15 @@
     try
     {
         // Load graph into runtime
-        auto loadingStatus = delegate->m_Runtime->LoadNetwork(networkId, std::move(optNet));
+        std::string errorMessage;
+        auto loadingStatus = delegate->m_Runtime->LoadNetwork(networkId,
+                                                              std::move(optNet),
+                                                              errorMessage,
+                                                              delegate->m_Options.GetNetworkProperties());
         if (loadingStatus != armnn::Status::Success)
         {
             // Optimize failed
-            throw armnn::Exception("TfLiteArmnnDelegate: Network could not be loaded!");;
+            throw armnn::Exception("TfLiteArmnnDelegate: Network could not be loaded:" + errorMessage);
         }
     }
     catch (std::exception& ex)
@@ -362,6 +370,12 @@
         throw armnn::Exception(exMessage.str());
     }
 
+    // Register debug callback function
+    if (delegate->m_Options.GetDebugCallbackFunction().has_value())
+    {
+        delegate->m_Runtime->RegisterDebugCallback(networkId, delegate->m_Options.GetDebugCallbackFunction().value());
+    }
+
     // Create a new SubGraph with networkId and runtime
     return new ArmnnSubgraph(networkId, delegate->m_Runtime.get(), inputBindings, outputBindings);
 }