Adds CustomAllocator interface and Sample App

 * Updates the runtime options with a CustomAllocatorMap which allows to define a CustomAllocator for specific backends
 * Change IBackendInternal interface to use a shared pointer to a custom allocator
 * Update ClBackend.hpp/cpp to use the CustomAllocator
 * Adds an example application and unit test which uses a CustomAllocator for GpuAcc
 * Refactor of the interface to use MemorySource instead of the user Mapping cl_mem directly
 * Modify the BackendRegistry to also hold a registry of CustomAllocators
 * BackendRegistry Deregister will also deregister any allocators associated with that backend id
 * set_global_allocator within the BaseMemoryManager so that it always matches the currently used allocator

Signed-off-by: Jan Eilers <jan.eilers@arm.com>
Change-Id: I156d819686021865f4375e6cb7a5c5dec8fee9e8
Signed-off-by: David Monahan <david.monahan@arm.com>
diff --git a/include/armnn/IRuntime.hpp b/include/armnn/IRuntime.hpp
index 8c269de..97a9c28 100644
--- a/include/armnn/IRuntime.hpp
+++ b/include/armnn/IRuntime.hpp
@@ -16,6 +16,7 @@
 
 #include <armnn/backends/ICustomAllocator.hpp>
 #include <memory>
+#include <map>
 
 namespace armnn
 {
@@ -103,8 +104,8 @@
             : m_GpuAccTunedParameters(nullptr)
             , m_EnableGpuProfiling(false)
             , m_DynamicBackendsPath("")
-            , m_CustomAllocator(nullptr)
             , m_ProtectedMode(false)
+            , m_CustomAllocatorMap()
         {}
 
         /// If set, uses the GpuAcc tuned parameters from the given object when executing GPU workloads.
@@ -118,17 +119,22 @@
         /// Only a single path is allowed for the override
         std::string m_DynamicBackendsPath;
 
-        /// A Custom Allocator used for allocation of working memory in the backends.
-        /// Set this for when you need to allocate Protected Working Memory, required for ProtectedMode
-        /// Only supported for GpuAcc
-        ICustomAllocator* m_CustomAllocator;
-
         /// Setting this flag will allow the user to create the Runtime in protected mode.
         /// It will run all the inferences on protected memory and will make sure that
         /// INetworkProperties::m_ImportEnabled set to true with MemorySource::DmaBufProtected option
-        /// This will use Protected Memory Allocator associated with the backend
+        /// This requires that the backend supports Protected Memory and has an allocator capable of
+        /// allocating Protected Memory associated with it.
         bool m_ProtectedMode;
 
+        /// @brief A map to define a custom memory allocator for specific backend Ids.
+        ///
+        /// @details  A Custom Allocator is used for allocation of working memory in the backends.
+        /// Set this if you need to take control of how memory is allocated on a backend. Required for
+        /// Protected Mode in order to correctly allocate Protected Memory
+        ///
+        /// @note Only supported for GpuAcc
+        std::map<BackendId, std::shared_ptr<ICustomAllocator>> m_CustomAllocatorMap;
+
         struct ExternalProfilingOptions
         {
             ExternalProfilingOptions()