IVGCVSW-5783 'Add AsyncExecution Capability'

* Added AsyncExecution to the BackendCapability enum class.
* Logged a warning if backends do not support AsyncExecution capability if AsyncNetwork is created.

Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: I49f8467297f4b6b8e414cb6a3638a7d3f1bb886a
diff --git a/include/armnn/Types.hpp b/include/armnn/Types.hpp
index 576e67e..07d38a3 100644
--- a/include/armnn/Types.hpp
+++ b/include/armnn/Types.hpp
@@ -203,6 +203,9 @@
     /// On the other hand, non-const weights can be accessed through inputs.
     NonConstWeights,
 
+    /// Asynchronous Execution.
+    AsyncExecution,
+
     // add new enum values here
 };
 
diff --git a/src/armnn/AsyncNetwork.cpp b/src/armnn/AsyncNetwork.cpp
index 4e3838b..230346a 100644
--- a/src/armnn/AsyncNetwork.cpp
+++ b/src/armnn/AsyncNetwork.cpp
@@ -8,6 +8,7 @@
 #include "Layer.hpp"
 #include "Profiling.hpp"
 
+#include <armnn/BackendHelper.hpp>
 #include <armnn/BackendRegistry.hpp>
 #include <armnn/Logging.hpp>
 #include <armnn/utility/Assert.hpp>
@@ -391,6 +392,18 @@
         }
     }
 
+    // Check backends support BackendCapability::AsyncExecution
+    for (auto const& backend : m_Backends)
+    {
+        if (!IsCapabilitySupported(backend.first, BackendCapability::AsyncExecution))
+        {
+            ARMNN_LOG(warning) << fmt::format("AsyncNetworkImpl() Backend: '{0}' does not support Async Execution. "
+                                              "Will fall back to default implementation.",
+                                              backend.first.Get());
+        }
+
+    }
+
     profiling::ProfilingGuid networkGuid = m_OptimizedNetwork->GetGuid();
     std::unique_ptr<profiling::TimelineUtilityMethods> timelineUtils =
             profiling::TimelineUtilityMethods::GetTimelineUtils(m_ProfilingService);
diff --git a/src/armnn/test/OptimizerTests.cpp b/src/armnn/test/OptimizerTests.cpp
index 896fdfd..95255c3 100644
--- a/src/armnn/test/OptimizerTests.cpp
+++ b/src/armnn/test/OptimizerTests.cpp
@@ -685,6 +685,9 @@
     BackendId backendId ="MockBackend";
     // MockBackend does not support the NonConstWeights capability
     BOOST_CHECK(!armnn::IsCapabilitySupported(backendId, armnn::BackendCapability::NonConstWeights));
+
+    // MockBackend does not support the AsyncExecution capability
+    BOOST_CHECK(!armnn::IsCapabilitySupported(backendId, armnn::BackendCapability::AsyncExecution));
 }
 
 BOOST_AUTO_TEST_CASE(BackendHintTest)
diff --git a/src/backends/backendsCommon/test/CompatibilityTests.cpp b/src/backends/backendsCommon/test/CompatibilityTests.cpp
index 915a015..0f889f4 100644
--- a/src/backends/backendsCommon/test/CompatibilityTests.cpp
+++ b/src/backends/backendsCommon/test/CompatibilityTests.cpp
@@ -125,6 +125,8 @@
 {
     auto refBackend  = std::make_unique<RefBackend>();
     BOOST_CHECK(refBackend->HasCapability(armnn::BackendCapability::NonConstWeights));
+
+    BOOST_CHECK(!refBackend->HasCapability(armnn::BackendCapability::AsyncExecution));
 }
 
 #endif
diff --git a/src/backends/cl/ClBackend.cpp b/src/backends/cl/ClBackend.cpp
index 928760e..33aff27 100644
--- a/src/backends/cl/ClBackend.cpp
+++ b/src/backends/cl/ClBackend.cpp
@@ -141,6 +141,16 @@
     return layerSupport;
 }
 
+bool ClBackend::HasCapability(BackendCapability capabilityClass) const
+{
+    auto search = gpuAccCapabilities.find(capabilityClass);
+    if (search != gpuAccCapabilities.end())
+    {
+        return true;
+    }
+    return false;
+}
+
 OptimizationViews ClBackend::OptimizeSubgraphView(const SubgraphView& subgraph,
                                                   const ModelOptions& modelOptions) const
 {
diff --git a/src/backends/cl/ClBackend.hpp b/src/backends/cl/ClBackend.hpp
index 2b19fc5..f9a5745 100644
--- a/src/backends/cl/ClBackend.hpp
+++ b/src/backends/cl/ClBackend.hpp
@@ -9,6 +9,10 @@
 namespace armnn
 {
 
+const std::set<armnn::BackendCapability> gpuAccCapabilities {
+    // add new capabilities here..
+};
+
 class ClBackend : public IBackendInternal
 {
 public:
@@ -49,6 +53,8 @@
 
     IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(
         const ModelOptions& modelOptions) const override;
+
+    bool HasCapability(BackendCapability capabilityClass) const override;
 };
 
 } // namespace armnn
diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp
index d48b32b..a1299fb 100644
--- a/src/backends/neon/NeonBackend.cpp
+++ b/src/backends/neon/NeonBackend.cpp
@@ -131,6 +131,16 @@
     return layerSupport;
 }
 
+bool NeonBackend::HasCapability(BackendCapability capabilityClass) const
+{
+    auto search = cpuAccCapabilities.find(capabilityClass);
+    if (search != cpuAccCapabilities.end())
+    {
+        return true;
+    }
+    return false;
+}
+
 OptimizationViews NeonBackend::OptimizeSubgraphView(const SubgraphView& subgraph) const
 {
     OptimizationViews optimizationViews;
diff --git a/src/backends/neon/NeonBackend.hpp b/src/backends/neon/NeonBackend.hpp
index 42c6666..34606f9 100644
--- a/src/backends/neon/NeonBackend.hpp
+++ b/src/backends/neon/NeonBackend.hpp
@@ -9,6 +9,10 @@
 namespace armnn
 {
 
+const std::set<armnn::BackendCapability> cpuAccCapabilities {
+    // add new capabilities here..
+};
+
 class NeonBackend : public IBackendInternal
 {
 public:
@@ -47,6 +51,8 @@
 
     IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(
         const ModelOptions& modelOptions) const override;
+
+    bool HasCapability(BackendCapability capabilityClass) const override;
 };
 
 } // namespace armnn
diff --git a/src/backends/reference/RefBackend.cpp b/src/backends/reference/RefBackend.cpp
index 53c55ab..85c6a2e 100644
--- a/src/backends/reference/RefBackend.cpp
+++ b/src/backends/reference/RefBackend.cpp
@@ -71,8 +71,8 @@
 
 bool RefBackend::HasCapability(BackendCapability capabilityClass) const
 {
-    auto search = backendCapabilities.find(capabilityClass);
-    if (search != backendCapabilities.end())
+    auto search = cpuRefCapabilities.find(capabilityClass);
+    if (search != cpuRefCapabilities.end())
     {
         return true;
     }
diff --git a/src/backends/reference/RefBackend.hpp b/src/backends/reference/RefBackend.hpp
index c92936c..3143173 100644
--- a/src/backends/reference/RefBackend.hpp
+++ b/src/backends/reference/RefBackend.hpp
@@ -9,7 +9,7 @@
 namespace armnn
 {
 
-const std::set<armnn::BackendCapability> backendCapabilities {
+const std::set<armnn::BackendCapability> cpuRefCapabilities {
     armnn::BackendCapability::NonConstWeights,
 };