COMPMID-485: Memory Manager

Change-Id: Ib421b7622838f050038cd81e7426bb1413a7d6e6
Reviewed-on: http://mpd-gerrit.cambridge.arm.com/87376
Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
diff --git a/arm_compute/runtime/Allocator.h b/arm_compute/runtime/Allocator.h
new file mode 100644
index 0000000..cf6f07b
--- /dev/null
+++ b/arm_compute/runtime/Allocator.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_ALLOCATOR_H__
+#define __ARM_COMPUTE_ALLOCATOR_H__
+
+#include "arm_compute/runtime/IAllocator.h"
+
+#include <cstddef>
+
+namespace arm_compute
+{
+/** Default malloc allocator implementation */
+class Allocator : public IAllocator
+{
+public:
+    /** Default constructor */
+    Allocator() = default;
+
+    // Inherited methods overridden:
+    void *allocate(size_t size, size_t alignment) override;
+    void free(void *ptr) override;
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_ALLOCATOR_H__ */
diff --git a/arm_compute/runtime/BlobLifetimeManager.h b/arm_compute/runtime/BlobLifetimeManager.h
new file mode 100644
index 0000000..ec43f47
--- /dev/null
+++ b/arm_compute/runtime/BlobLifetimeManager.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_BLOBLIFETIMEMANAGER_H__
+#define __ARM_COMPUTE_BLOBLIFETIMEMANAGER_H__
+
+#include "arm_compute/runtime/ILifetimeManager.h"
+
+#include "arm_compute/runtime/IMemoryGroup.h"
+#include "arm_compute/runtime/Types.h"
+
+#include <cstddef>
+#include <map>
+#include <vector>
+
+namespace arm_compute
+{
+class IMemoryGroup;
+
+/** Class that tracks the lifetime of registered tensors and calculates the systems memory requirements in terms of blobs */
+class BlobLifetimeManager : public ILifetimeManager
+{
+public:
+    /** Constructor */
+    BlobLifetimeManager();
+    /** Prevent instances of this class to be copy constructed */
+    BlobLifetimeManager(const BlobLifetimeManager &) = delete;
+    /** Prevent instances of this class to be copied */
+    BlobLifetimeManager &operator=(const BlobLifetimeManager &) = delete;
+    /** Allow instances of this class to be move constructed */
+    BlobLifetimeManager(BlobLifetimeManager &&) = default;
+    /** Allow instances of this class to be moved */
+    BlobLifetimeManager &operator=(BlobLifetimeManager &&) = default;
+
+    // Inherited methods overridden:
+    void register_group(IMemoryGroup *group) override;
+    void start_lifetime(void *obj) override;
+    void end_lifetime(void *obj, void **handle, size_t size) override;
+    std::unique_ptr<IMemoryPool> create_pool(IAllocator *allocator) override;
+    bool        are_all_finalized() const override;
+    MappingType mapping_type() const override;
+
+private:
+    /** Update blobs and mappings */
+    void update_blobs_and_mappings();
+
+private:
+    /** Element struct */
+    struct Element
+    {
+        Element(void *id_ = nullptr, void **handle_ = nullptr, size_t size_ = 0, bool status_ = false)
+            : id(id_), handle(handle_), size(size_), status(status_)
+        {
+        }
+        void *id;      /**< Element id */
+        void **handle; /**< Element's memory handle */
+        size_t size;   /**< Element's size */
+        bool   status; /**< Lifetime status */
+    };
+
+    IMemoryGroup        *_active_group;                               /**< Active group */
+    std::vector<Element> _active_elements;                            /**< A map that contains the active elements */
+    std::map<IMemoryGroup *, std::vector<Element>> _finalized_groups; /**< A map that contains the finalized groups */
+    std::vector<size_t> _blobs;
+};
+} // arm_compute
+#endif /* __ARM_COMPUTE_BLOBLIFETIMEMANAGER_H__ */
diff --git a/arm_compute/runtime/BlobMemoryPool.h b/arm_compute/runtime/BlobMemoryPool.h
new file mode 100644
index 0000000..f2be2dd
--- /dev/null
+++ b/arm_compute/runtime/BlobMemoryPool.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_BLOBMEMORYPOOL_H__
+#define __ARM_COMPUTE_BLOBMEMORYPOOL_H__
+
+#include "arm_compute/runtime/IMemoryPool.h"
+
+#include "arm_compute/runtime/IAllocator.h"
+#include "arm_compute/runtime/Types.h"
+
+#include <cstddef>
+#include <vector>
+
+namespace arm_compute
+{
+/** Blob memory pool */
+class BlobMemoryPool : public IMemoryPool
+{
+public:
+    /** Default Constructor */
+    BlobMemoryPool(IAllocator *allocator, std::vector<size_t> blob_sizes);
+    /** Default Destructor */
+    ~BlobMemoryPool();
+    /** Prevent instances of this class to be copy constructed */
+    BlobMemoryPool(const BlobMemoryPool &) = delete;
+    /** Prevent instances of this class to be copy assigned */
+    BlobMemoryPool &operator=(const BlobMemoryPool &) = delete;
+    /** Allow instances of this class to be move constructed */
+    BlobMemoryPool(BlobMemoryPool &&) = default;
+    /** Allow instances of this class to be move assigned */
+    BlobMemoryPool &operator=(BlobMemoryPool &&) = default;
+
+    // Inherited methods overridden:
+    void acquire(MemoryMappings &handles) override;
+    void release(MemoryMappings &handles) override;
+    MappingType                  mapping_type() const override;
+    std::unique_ptr<IMemoryPool> duplicate() override;
+
+private:
+    /** Allocates internal blobs
+     *
+     * @param sizes Size of each blob
+     */
+    void allocate_blobs(const std::vector<size_t> &sizes);
+    /** Frees blobs **/
+    void free_blobs();
+
+private:
+    IAllocator         *_allocator;  /**< Allocator to use for internal allocation */
+    std::vector<void *> _blobs;      /**< Vector holding all the memory blobs */
+    std::vector<size_t> _blob_sizes; /**< Sizes of each blob */
+};
+} // arm_compute
+#endif /* __ARM_COMPUTE_BLOBMEMORYPOOL_H__ */
diff --git a/arm_compute/runtime/CL/CLBufferAllocator.h b/arm_compute/runtime/CL/CLBufferAllocator.h
new file mode 100644
index 0000000..05b0363
--- /dev/null
+++ b/arm_compute/runtime/CL/CLBufferAllocator.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_CLBUFFERALLOCATOR_H__
+#define __ARM_COMPUTE_CLBUFFERALLOCATOR_H__
+
+#include "arm_compute/runtime/IAllocator.h"
+
+#include "arm_compute/core/CL/OpenCL.h"
+#include "arm_compute/runtime/CL/CLScheduler.h"
+
+#include <cstddef>
+
+namespace arm_compute
+{
+/** Default OpenCL cl buffer allocator implementation */
+class CLBufferAllocator : public IAllocator
+{
+public:
+    /** Default constructor */
+    explicit CLBufferAllocator(cl::Context context = CLScheduler::get().context());
+
+    // Inherited methods overridden:
+    void *allocate(size_t size, size_t alignment) override;
+    void free(void *ptr) override;
+
+private:
+    cl::Context _context;
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_CLBUFFERALLOCATOR_H__ */
diff --git a/arm_compute/runtime/CL/CLMemoryGroup.h b/arm_compute/runtime/CL/CLMemoryGroup.h
new file mode 100644
index 0000000..a6f3eb1
--- /dev/null
+++ b/arm_compute/runtime/CL/CLMemoryGroup.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_CLMEMORYGROUP_H__
+#define __ARM_COMPUTE_CLMEMORYGROUP_H__
+
+#include "arm_compute/runtime/MemoryGroupBase.h"
+
+#include "arm_compute/core/CL/OpenCL.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+
+namespace arm_compute
+{
+using CLMemoryGroup = MemoryGroupBase<CLTensor>;
+
+template <>
+inline void MemoryGroupBase<CLTensor>::associate_memory_group(CLTensor *obj)
+{
+    ARM_COMPUTE_ERROR_ON(obj == nullptr);
+    auto allocator = dynamic_cast<CLTensorAllocator *>(obj->allocator());
+    ARM_COMPUTE_ERROR_ON(allocator == nullptr);
+    allocator->set_associated_memory_group(this);
+}
+} // arm_compute
+#endif /*__ARM_COMPUTE_CLMEMORYGROUP_H__ */
diff --git a/arm_compute/runtime/CL/CLTensorAllocator.h b/arm_compute/runtime/CL/CLTensorAllocator.h
index ed371e0..682de17 100644
--- a/arm_compute/runtime/CL/CLTensorAllocator.h
+++ b/arm_compute/runtime/CL/CLTensorAllocator.h
@@ -24,19 +24,27 @@
 #ifndef __ARM_COMPUTE_CLTENSORALLOCATOR_H__
 #define __ARM_COMPUTE_CLTENSORALLOCATOR_H__
 
-#include "arm_compute/core/CL/OpenCL.h"
 #include "arm_compute/runtime/ITensorAllocator.h"
 
+#include "arm_compute/core/CL/OpenCL.h"
+
 #include <cstdint>
 
 namespace arm_compute
 {
+class CLTensor;
+template <typename>
+class MemoryGroupBase;
+using CLMemoryGroup = MemoryGroupBase<CLTensor>;
+
 /** Basic implementation of a CL memory tensor allocator. */
 class CLTensorAllocator : public ITensorAllocator
 {
 public:
     /** Default constructor. */
-    CLTensorAllocator();
+    CLTensorAllocator(CLTensor *owner = nullptr);
+    /** Default destructor */
+    ~CLTensorAllocator();
     /** Prevent instances of this class from being copied (As this class contains pointers). */
     CLTensorAllocator(const CLTensorAllocator &) = delete;
     /** Prevent instances of this class from being copy assigned (As this class contains pointers). */
@@ -45,8 +53,6 @@
     CLTensorAllocator(CLTensorAllocator &&) = default;
     /** Allow instances of this class to be moved */
     CLTensorAllocator &operator=(CLTensorAllocator &&) = default;
-    /** Default destructor */
-    ~CLTensorAllocator() = default;
 
     /** Interface to be implemented by the child class to return the pointer to the mapped data. */
     uint8_t *data();
@@ -85,6 +91,11 @@
      *
      */
     void free() override;
+    /** Associates the tensor with a memory group
+     *
+     * @param[in] associated_memory_group Memory group to associate the tensor with
+     */
+    void set_associated_memory_group(CLMemoryGroup *associated_memory_group);
 
 protected:
     /** Call map() on the OpenCL buffer.
@@ -96,8 +107,10 @@
     void unlock() override;
 
 private:
-    cl::Buffer _buffer;  /**< OpenCL buffer containing the tensor data. */
-    uint8_t   *_mapping; /**< Pointer to the CPU mapping of the OpenCL buffer. */
+    CLMemoryGroup *_associated_memory_group; /**< Registered memory manager */
+    cl::Buffer     _buffer;                  /**< OpenCL buffer containing the tensor data. */
+    uint8_t       *_mapping;                 /**< Pointer to the CPU mapping of the OpenCL buffer. */
+    CLTensor      *_owner;                   /**< Owner of the allocator */
 };
 }
 #endif /* __ARM_COMPUTE_CLTENSORALLOCATOR_H__ */
diff --git a/arm_compute/runtime/CL/functions/CLConvolutionLayer.h b/arm_compute/runtime/CL/functions/CLConvolutionLayer.h
index 2057b6f..cd1ea70 100644
--- a/arm_compute/runtime/CL/functions/CLConvolutionLayer.h
+++ b/arm_compute/runtime/CL/functions/CLConvolutionLayer.h
@@ -34,7 +34,11 @@
 #include "arm_compute/core/CL/kernels/CLIm2ColKernel.h"
 #include "arm_compute/core/CL/kernels/CLWeightsReshapeKernel.h"
 #include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLMemoryGroup.h"
 #include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/IMemoryManager.h"
+
+#include <memory>
 
 namespace arm_compute
 {
@@ -48,7 +52,7 @@
 {
 public:
     /** Constructor */
-    CLConvolutionLayerReshapeWeights();
+    CLConvolutionLayerReshapeWeights(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  weights      Weights tensor. Weights are 4D tensor with dimensions [kernel_x, kernel_y, IFM, OFM]. Data type supported: QS8/QS16/F16/F32.
@@ -62,6 +66,7 @@
     void run() override;
 
 private:
+    CLMemoryGroup            _memory_group;
     CLWeightsReshapeKernel   _weights_reshape_kernel;
     CLGEMMTranspose1xWKernel _weights_transposed_kernel;
     CLTensor                 _weights_reshaped;
@@ -81,7 +86,7 @@
 {
 public:
     /** Default constructor */
-    CLConvolutionLayer();
+    CLConvolutionLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input        Source tensor. 3 lower dimensions represent a single input [width, height, IFM],
@@ -101,6 +106,7 @@
     void run() override;
 
 private:
+    CLMemoryGroup                    _memory_group;
     CLConvolutionLayerReshapeWeights _reshape_weights;
     CLIm2ColKernel                   _input_im2col_kernel;
     CLGEMMInterleave4x4Kernel        _input_interleave_kernel;
diff --git a/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h b/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h
index e076f51..f71e2a3 100644
--- a/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h
+++ b/arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h
@@ -30,6 +30,7 @@
 #include "arm_compute/core/CL/kernels/CLGEMMMatrixMultiplyKernel.h"
 #include "arm_compute/core/CL/kernels/CLIm2ColKernel.h"
 #include "arm_compute/core/CL/kernels/CLTransposeKernel.h"
+#include "arm_compute/runtime/CL/CLMemoryGroup.h"
 #include "arm_compute/runtime/CL/CLTensor.h"
 
 namespace arm_compute
@@ -64,7 +65,7 @@
 {
 public:
     /** Constructor */
-    CLFullyConnectedLayer();
+    CLFullyConnectedLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input                Source tensor. Data type supported: QS8/QS16/F16/F32.
@@ -83,6 +84,7 @@
     void configure_fc_fc(const ICLTensor *input, const ICLTensor *weights, ICLTensor *output);
     void configure_conv_fc(const ICLTensor *input, const ICLTensor *weights, ICLTensor *output);
 
+    CLMemoryGroup                       _memory_group;
     CLIm2ColKernel                      _im2col_kernel;
     CLFullyConnectedLayerReshapeWeights _reshape_weights_kernel;
     CLGEMMMatrixMultiplyKernel          _mm_kernel;
diff --git a/arm_compute/runtime/CL/functions/CLSoftmaxLayer.h b/arm_compute/runtime/CL/functions/CLSoftmaxLayer.h
index 18f7a02..70a265c 100644
--- a/arm_compute/runtime/CL/functions/CLSoftmaxLayer.h
+++ b/arm_compute/runtime/CL/functions/CLSoftmaxLayer.h
@@ -25,8 +25,12 @@
 #define __ARM_COMPUTE_CLSOFTMAXLAYER_H__
 
 #include "arm_compute/core/CL/kernels/CLSoftmaxLayerKernel.h"
+#include "arm_compute/runtime/CL/CLMemoryGroup.h"
 #include "arm_compute/runtime/CL/CLTensor.h"
 #include "arm_compute/runtime/IFunction.h"
+#include "arm_compute/runtime/IMemoryManager.h"
+
+#include <memory>
 
 namespace arm_compute
 {
@@ -46,7 +50,7 @@
 {
 public:
     /** Constructor */
-    CLSoftmaxLayer();
+    CLSoftmaxLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input  Source tensor. Data types supported: QS8/QS16/F16/F32
@@ -58,6 +62,7 @@
     void run() override;
 
 private:
+    CLMemoryGroup               _memory_group;
     CLLogits1DMaxKernel         _max_kernel;
     CLLogits1DShiftExpSumKernel _shift_exp_sum_kernel;
     CLLogits1DNormKernel        _norm_kernel;
diff --git a/arm_compute/runtime/IAllocator.h b/arm_compute/runtime/IAllocator.h
new file mode 100644
index 0000000..3edb34a
--- /dev/null
+++ b/arm_compute/runtime/IAllocator.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_IALLOCATOR_H__
+#define __ARM_COMPUTE_IALLOCATOR_H__
+
+#include <cstddef>
+
+namespace arm_compute
+{
+/** Allocator interface */
+class IAllocator
+{
+public:
+    /** Default virtual destructor. */
+    virtual ~IAllocator() = default;
+    /** Interface to be implemented by the child class to allocate bytes
+     *
+     * @param[in] size      Size to allocate
+     * @param[in] alignment Alignment that the returned pointer should comply with
+     *
+     * @return A pointer to the allocated memory
+     */
+    virtual void *allocate(size_t size, size_t alignment) = 0;
+    /** Interface to be implemented by the child class to free the allocated tensor */
+    virtual void free(void *ptr) = 0;
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_IALLOCATOR_H__ */
diff --git a/arm_compute/runtime/ILifetimeManager.h b/arm_compute/runtime/ILifetimeManager.h
new file mode 100644
index 0000000..4f9af6f
--- /dev/null
+++ b/arm_compute/runtime/ILifetimeManager.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_ILIFETIMEMANAGER_H__
+#define __ARM_COMPUTE_ILIFETIMEMANAGER_H__
+
+#include "arm_compute/runtime/IMemoryPool.h"
+#include "arm_compute/runtime/Types.h"
+
+#include <cstddef>
+#include <vector>
+
+namespace arm_compute
+{
+class IMemoryGroup;
+class IAllocator;
+
+/** Interface for managing the lifetime of objects */
+class ILifetimeManager
+{
+public:
+    /** Virtual Destructor */
+    virtual ~ILifetimeManager() = default;
+    /** Registers a group to the lifetime manager and assigns a group id
+     *
+     * @return The group id of the group
+     */
+    virtual void register_group(IMemoryGroup *group) = 0;
+    /** Registers and starts lifetime of an object
+     *
+     * @param[in] obj Object to register
+     */
+    virtual void start_lifetime(void *obj) = 0;
+    /** Ends lifetime of an object
+     *
+     * @param[in] obj    Object
+     * @param[in] handle Memory handle of the object
+     * @param[in] size   Size of the given object at given time
+     */
+    virtual void end_lifetime(void *obj, void **handle, size_t size) = 0;
+    /** Creates a memory pool depending on the memory requirements
+     *
+     * @param allocator Allocator to use
+     *
+     * @return A memory pool
+     */
+    virtual std::unique_ptr<IMemoryPool> create_pool(IAllocator *allocator) = 0;
+    /** Checks if the lifetime of the registered object is complete
+     *
+     * @return True if all object lifetimes are finalized else false.
+     */
+    virtual bool are_all_finalized() const = 0;
+    /** Returns the type of mappings that the lifetime manager returns
+     *
+     * @return Mapping type of the lifetime manager
+     */
+    virtual MappingType mapping_type() const = 0;
+};
+} // arm_compute
+#endif /* __ARM_COMPUTE_ILIFETIMEMANAGER_H__ */
diff --git a/arm_compute/runtime/IMemoryGroup.h b/arm_compute/runtime/IMemoryGroup.h
new file mode 100644
index 0000000..be03ea4
--- /dev/null
+++ b/arm_compute/runtime/IMemoryGroup.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_IMEMORYGROUP_H__
+#define __ARM_COMPUTE_IMEMORYGROUP_H__
+
+#include "arm_compute/runtime/Types.h"
+
+namespace arm_compute
+{
+/** Memory group interface */
+class IMemoryGroup
+{
+public:
+    /** Default virtual destructor */
+    virtual ~IMemoryGroup() = default;
+    /** Acquires backing memory for the whole group */
+    virtual void acquire() = 0;
+    /** Releases backing memory of the whole group */
+    virtual void release() = 0;
+    /** Gets the memory mapping of the group */
+    virtual MemoryMappings &mappings() = 0;
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_IMEMORYGROUP_H__ */
diff --git a/arm_compute/runtime/IMemoryManager.h b/arm_compute/runtime/IMemoryManager.h
new file mode 100644
index 0000000..00aa566
--- /dev/null
+++ b/arm_compute/runtime/IMemoryManager.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_IMEMORYMANAGER_H__
+#define __ARM_COMPUTE_IMEMORYMANAGER_H__
+
+#include "arm_compute/runtime/ILifetimeManager.h"
+#include "arm_compute/runtime/IPoolManager.h"
+
+#include <cstddef>
+
+namespace arm_compute
+{
+class IMemoryGroup;
+
+/** Memory manager interface to handle allocations of backing memory */
+class IMemoryManager
+{
+public:
+    /** Default virtual destructor */
+    virtual ~IMemoryManager() = default;
+    /** Returns the lifetime manager used by the memory manager
+     *
+     * @return The lifetime manager
+     */
+    virtual ILifetimeManager *lifetime_manager() = 0;
+    /** Returns the pool manager used by the memory manager
+     *
+     * @return The pool manager
+     */
+    virtual IPoolManager *pool_manager() = 0;
+    /** Finalize memory manager */
+    virtual void finalize() = 0;
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_IMEMORYMANAGER_H__ */
diff --git a/arm_compute/runtime/IMemoryPool.h b/arm_compute/runtime/IMemoryPool.h
new file mode 100644
index 0000000..aee6ad2
--- /dev/null
+++ b/arm_compute/runtime/IMemoryPool.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_IMEMORYPOOL_H__
+#define __ARM_COMPUTE_IMEMORYPOOL_H__
+
+#include "arm_compute/runtime/Types.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+namespace arm_compute
+{
+/** Memory Pool Inteface */
+class IMemoryPool
+{
+public:
+    /** Default Virtual Destructor */
+    virtual ~IMemoryPool() = default;
+    /** Sets occupant to the memory pool
+     *
+     * @param[in] handles A vector of pairs (handle, index)
+     */
+    virtual void acquire(MemoryMappings &handles) = 0;
+    /** Releases a memory block
+     *
+     * @param[in] handles A vector containing a pair of handles and indices
+     */
+    virtual void release(MemoryMappings &handles) = 0;
+    /** Returns the mapping types that this pool accepts
+     *
+     * @return the mapping type of the memory
+     */
+    virtual MappingType mapping_type() const = 0;
+    /** Duplicates the existing memory pool
+     *
+     * @return A duplicate of the existing pool
+     */
+    virtual std::unique_ptr<IMemoryPool> duplicate() = 0;
+};
+} // arm_compute
+#endif /* __ARM_COMPUTE_IMEMORYPOOL_H__ */
diff --git a/arm_compute/runtime/IPoolManager.h b/arm_compute/runtime/IPoolManager.h
new file mode 100644
index 0000000..03cccdd
--- /dev/null
+++ b/arm_compute/runtime/IPoolManager.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_IPOOLMANAGER_H__
+#define __ARM_COMPUTE_IPOOLMANAGER_H__
+
+#include <memory>
+
+namespace arm_compute
+{
+class IMemoryPool;
+
+/** Memory pool manager interface */
+class IPoolManager
+{
+public:
+    /** Default virtual destructor */
+    virtual ~IPoolManager() = default;
+    /** Locks a pool for execution
+     *
+     * @return Locked pool that workload will be mapped on
+     */
+    virtual IMemoryPool *lock_pool() = 0;
+    /** Releases memory pool
+     *
+     * @param[in] pool Memory pool to release
+     */
+    virtual void unlock_pool(IMemoryPool *pool) = 0;
+    /** Register pool to be managed by the pool
+     *
+     * @note Ownership of the pools is being transferred to the pool manager
+     *
+     * @param[in] pool Pool to be managed
+     */
+    virtual void register_pool(std::unique_ptr<IMemoryPool> pool) = 0;
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_IPOOLMANAGER_H__ */
diff --git a/arm_compute/runtime/MemoryGroup.h b/arm_compute/runtime/MemoryGroup.h
new file mode 100644
index 0000000..d3f647e
--- /dev/null
+++ b/arm_compute/runtime/MemoryGroup.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_MEMORYGROUP_H__
+#define __ARM_COMPUTE_MEMORYGROUP_H__
+
+#include "arm_compute/runtime/MemoryGroupBase.h"
+
+#include "arm_compute/runtime/Tensor.h"
+
+namespace arm_compute
+{
+using MemoryGroup = MemoryGroupBase<Tensor>;
+
+template <>
+inline void MemoryGroupBase<Tensor>::associate_memory_group(Tensor *obj)
+{
+    ARM_COMPUTE_ERROR_ON(obj == nullptr);
+    auto allocator = dynamic_cast<TensorAllocator *>(obj->allocator());
+    ARM_COMPUTE_ERROR_ON(allocator == nullptr);
+    allocator->set_associated_memory_group(this);
+}
+} // arm_compute
+#endif /*__ARM_COMPUTE_MEMORYGROUP_H__ */
diff --git a/arm_compute/runtime/MemoryGroupBase.h b/arm_compute/runtime/MemoryGroupBase.h
new file mode 100644
index 0000000..ab8acb3
--- /dev/null
+++ b/arm_compute/runtime/MemoryGroupBase.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_MEMORYGROUPBASE_H__
+#define __ARM_COMPUTE_MEMORYGROUPBASE_H__
+
+#include "arm_compute/runtime/IMemoryGroup.h"
+
+#include "arm_compute/runtime/IMemoryManager.h"
+#include "arm_compute/runtime/IMemoryPool.h"
+
+#include <cstddef>
+#include <memory>
+
+namespace arm_compute
+{
+/** Memory group */
+template <typename TensorType>
+class MemoryGroupBase : public IMemoryGroup
+{
+public:
+    /** Default Constructor */
+    MemoryGroupBase(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
+    /** Default destructor */
+    ~MemoryGroupBase() = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers). */
+    MemoryGroupBase(const MemoryGroupBase &) = delete;
+    /** Prevent instances of this class from being copy assigned (As this class contains pointers). */
+    MemoryGroupBase &operator=(const MemoryGroupBase &) = delete;
+    /** Allow instances of this class to be moved */
+    MemoryGroupBase(MemoryGroupBase &&) = default;
+    /** Allow instances of this class to be moved */
+    MemoryGroupBase &operator=(MemoryGroupBase &&) = default;
+    /** Sets a object to be managed by the given memory group
+     *
+     * @note Manager must not be finalized
+     *
+     * @param[in] obj Object to be managed
+     */
+    void manage(TensorType *obj);
+    /** Finalizes memory for a given object
+     *
+     * @note Manager must not be finalized
+     *
+     * @param[in] obj    Object to request memory for
+     * @param[in] handle Handle to store the memory
+     * @param[in] size   Size of memory to allocate
+     */
+    void finalize_memory(TensorType *obj, void **handle, size_t size);
+
+    // Inherited methods overridden:
+    void            acquire() override;
+    void            release() override;
+    MemoryMappings &mappings() override;
+
+private:
+    void associate_memory_group(TensorType *obj);
+
+private:
+    std::shared_ptr<IMemoryManager> _memory_manager; /**< Memory manager to be used by the group */
+    IMemoryPool                    *_pool;           /**< Memory pool that the group is scheduled with */
+    MemoryMappings                  _mappings;       /**< Memory mappings of the group */
+};
+
+template <typename TensorType>
+inline MemoryGroupBase<TensorType>::MemoryGroupBase(std::shared_ptr<IMemoryManager> memory_manager)
+    : _memory_manager(std::move(memory_manager)), _pool(nullptr), _mappings()
+{
+    if(_memory_manager)
+    {
+        ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());
+    }
+}
+
+template <typename TensorType>
+inline void MemoryGroupBase<TensorType>::manage(TensorType *obj)
+{
+    if(_memory_manager)
+    {
+        ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());
+
+        // Defer registration to the first managed object
+        _memory_manager->lifetime_manager()->register_group(this);
+
+        // Associate this memory group with the tensor
+        associate_memory_group(obj);
+
+        // Start object lifetime
+        _memory_manager->lifetime_manager()->start_lifetime(obj);
+    }
+}
+
+template <typename TensorType>
+inline void MemoryGroupBase<TensorType>::finalize_memory(TensorType *obj, void **handle, size_t size)
+{
+    if(_memory_manager)
+    {
+        ARM_COMPUTE_ERROR_ON(!_memory_manager->lifetime_manager());
+        _memory_manager->lifetime_manager()->end_lifetime(obj, handle, size);
+    }
+}
+
+template <typename TensorType>
+inline void MemoryGroupBase<TensorType>::acquire()
+{
+    if(!_mappings.empty())
+    {
+        ARM_COMPUTE_ERROR_ON(!_memory_manager->pool_manager());
+        _pool = _memory_manager->pool_manager()->lock_pool();
+        _pool->acquire(_mappings);
+    }
+}
+
+template <typename TensorType>
+inline void MemoryGroupBase<TensorType>::release()
+{
+    if(_pool != nullptr)
+    {
+        ARM_COMPUTE_ERROR_ON(!_memory_manager->pool_manager());
+        ARM_COMPUTE_ERROR_ON(_mappings.empty());
+        _pool->release(_mappings);
+        _memory_manager->pool_manager()->unlock_pool(_pool);
+        _pool = nullptr;
+    }
+}
+
+template <typename TensorType>
+inline MemoryMappings &MemoryGroupBase<TensorType>::mappings()
+{
+    return _mappings;
+}
+
+template <typename TensorType>
+inline void MemoryGroupBase<TensorType>::associate_memory_group(TensorType *)
+{
+    ARM_COMPUTE_ERROR("Must be implemented by child class");
+}
+} // arm_compute
+#endif /*__ARM_COMPUTE_MEMORYGROUPBASE_H__ */
diff --git a/arm_compute/runtime/MemoryManagerOnDemand.h b/arm_compute/runtime/MemoryManagerOnDemand.h
new file mode 100644
index 0000000..ad4b831
--- /dev/null
+++ b/arm_compute/runtime/MemoryManagerOnDemand.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_MEMORYMANAGERONDEMAND_H__
+#define __ARM_COMPUTE_MEMORYMANAGERONDEMAND_H__
+
+#include "arm_compute/runtime/IMemoryManager.h"
+
+#include "IAllocator.h"
+#include "arm_compute/runtime/ILifetimeManager.h"
+#include "arm_compute/runtime/IMemoryGroup.h"
+#include "arm_compute/runtime/IPoolManager.h"
+
+#include <memory>
+#include <set>
+
+namespace arm_compute
+{
+class IAllocator;
+
+/** On-demand memory manager */
+class MemoryManagerOnDemand : public IMemoryManager
+{
+public:
+    /** Default Constructor */
+    MemoryManagerOnDemand(std::shared_ptr<ILifetimeManager> lifetime_manager, std::shared_ptr<IPoolManager> pool_manager);
+    /** Prevent instances of this class to be copy constructed */
+    MemoryManagerOnDemand(const MemoryManagerOnDemand &) = delete;
+    /** Prevent instances of this class to be copied */
+    MemoryManagerOnDemand &operator=(const MemoryManagerOnDemand &) = delete;
+    /** Allow instances of this class to be move constructed */
+    MemoryManagerOnDemand(MemoryManagerOnDemand &&) = default;
+    /** Allow instances of this class to be moved */
+    MemoryManagerOnDemand &operator=(MemoryManagerOnDemand &&) = default;
+    /** Sets the number of pools to create
+     *
+     * @param[in] num_pools Number of pools
+     */
+    void set_num_pools(unsigned int num_pools);
+    /** Sets the allocator to be used for configuring the pools
+     *
+     * @param[in] allocator Allocator to use
+     */
+    void set_allocator(IAllocator *allocator);
+    /** Checks if the memory manager has been finalized
+     *
+     * @return True if the memory manager has been finalized else false
+     */
+    bool is_finalized() const;
+
+    // Inherited methods overridden:
+    ILifetimeManager *lifetime_manager() override;
+    IPoolManager     *pool_manager() override;
+    void              finalize() override;
+
+private:
+    std::shared_ptr<ILifetimeManager> _lifetime_mgr; /**< Lifetime manager */
+    std::shared_ptr<IPoolManager>     _pool_mgr;     /**< Memory pool manager */
+    IAllocator                       *_allocator;    /**< Allocator used for backend allocations */
+    bool                              _is_finalized; /**< Flag that notes if the memory manager has been finalized */
+    unsigned int                      _num_pools;    /**< Number of pools to create */
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_MEMORYMANAGERONDEMAND_H__ */
diff --git a/arm_compute/runtime/NEON/functions/NEConvolutionLayer.h b/arm_compute/runtime/NEON/functions/NEConvolutionLayer.h
index 1bd7e6a..8e040b3 100644
--- a/arm_compute/runtime/NEON/functions/NEConvolutionLayer.h
+++ b/arm_compute/runtime/NEON/functions/NEConvolutionLayer.h
@@ -34,6 +34,7 @@
 #include "arm_compute/core/NEON/kernels/NEIm2ColKernel.h"
 #include "arm_compute/core/NEON/kernels/NEWeightsReshapeKernel.h"
 #include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/MemoryGroup.h"
 #include "arm_compute/runtime/Tensor.h"
 
 namespace arm_compute
@@ -48,7 +49,7 @@
 {
 public:
     /** Constructor */
-    NEConvolutionLayerReshapeWeights();
+    NEConvolutionLayerReshapeWeights(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  weights      Weights tensor. Weights are 4D tensor with dimensions [kernel_x, kernel_y, IFM, OFM]. Data type supported: QS8/QS16/F32.
@@ -62,6 +63,7 @@
     void run() override;
 
 private:
+    MemoryGroup              _memory_group;
     NEWeightsReshapeKernel   _weights_reshape_kernel;
     NEGEMMTranspose1xWKernel _weights_transposed_kernel;
     Tensor                   _weights_reshaped;
@@ -79,7 +81,7 @@
 {
 public:
     /** Constructor */
-    NEConvolutionLayer();
+    NEConvolutionLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input        Source tensor. 3 lower dimensions represent a single input [width, height, IFM],
@@ -98,6 +100,7 @@
     void run() override;
 
 private:
+    MemoryGroup                      _memory_group;
     NEIm2ColKernel                   _input_im2col_kernel;
     NEGEMMInterleave4x4Kernel        _input_interleave_kernel;
     NEConvolutionLayerReshapeWeights _reshape_weights;
diff --git a/arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h b/arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h
index 08099b8..463a7d5 100644
--- a/arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h
+++ b/arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h
@@ -32,6 +32,7 @@
 #include "arm_compute/core/NEON/kernels/NEGEMMTranspose1xWKernel.h"
 #include "arm_compute/core/NEON/kernels/NEIm2ColKernel.h"
 #include "arm_compute/core/NEON/kernels/NETransposeKernel.h"
+#include "arm_compute/runtime/MemoryGroup.h"
 #include "arm_compute/runtime/Tensor.h"
 
 namespace arm_compute
@@ -47,7 +48,7 @@
 {
 public:
     /** Constructor */
-    NEFullyConnectedLayerReshapeWeights();
+    NEFullyConnectedLayerReshapeWeights(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input               Weights tensor. The weights must be 2 dimensional. Data types supported: QS8/QS16/F32.
@@ -61,6 +62,7 @@
     void run() override;
 
 private:
+    MemoryGroup              _memory_group;
     NETransposeKernel        _transpose_kernel;
     NEGEMMTranspose1xWKernel _transpose1xW_kernel;
     Tensor                   _transpose_output;
@@ -81,7 +83,7 @@
 {
 public:
     /** Constructor */
-    NEFullyConnectedLayer();
+    NEFullyConnectedLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input                Source tensor. Data type supported: QS8/QS16/F32.
@@ -97,6 +99,7 @@
     void run() override;
 
 private:
+    MemoryGroup                         _memory_group;
     NEIm2ColKernel                      _im2col_kernel;
     NEFullyConnectedLayerReshapeWeights _reshape_weights_kernel;
     NEGEMMInterleave4x4Kernel           _interleave4x4_kernel;
diff --git a/arm_compute/runtime/NEON/functions/NESoftmaxLayer.h b/arm_compute/runtime/NEON/functions/NESoftmaxLayer.h
index 01402ae..a265f70 100644
--- a/arm_compute/runtime/NEON/functions/NESoftmaxLayer.h
+++ b/arm_compute/runtime/NEON/functions/NESoftmaxLayer.h
@@ -27,6 +27,7 @@
 #include "arm_compute/core/NEON/kernels/NEFillBorderKernel.h"
 #include "arm_compute/core/NEON/kernels/NESoftmaxLayerKernel.h"
 #include "arm_compute/runtime/IFunction.h"
+#include "arm_compute/runtime/MemoryGroup.h"
 #include "arm_compute/runtime/Tensor.h"
 
 namespace arm_compute
@@ -47,7 +48,7 @@
 {
 public:
     /** Constructor */
-    NESoftmaxLayer();
+    NESoftmaxLayer(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
     /** Set the input and output tensors.
      *
      * @param[in]  input  Source tensor. Data types supported: QS8/QS16/F16/F32.
@@ -59,6 +60,7 @@
     void run() override;
 
 private:
+    MemoryGroup                 _memory_group;
     NELogits1DMaxKernel         _max_kernel;
     NELogits1DShiftExpSumKernel _shift_exp_sum_kernel;
     NELogits1DNormKernel        _norm_kernel;
diff --git a/arm_compute/runtime/PoolManager.h b/arm_compute/runtime/PoolManager.h
new file mode 100644
index 0000000..6549350
--- /dev/null
+++ b/arm_compute/runtime/PoolManager.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_POOLMANAGER_H__
+#define __ARM_COMPUTE_POOLMANAGER_H__
+
+#include "arm_compute/runtime/IPoolManager.h"
+
+#include "arm_compute/core/Error.h"
+#include "arm_compute/runtime/IMemoryPool.h"
+#include "support/Mutex.h"
+#include "support/Semaphore.h"
+
+#include <cstddef>
+#include <list>
+#include <memory>
+
+namespace arm_compute
+{
+/** Memory pool manager */
+class PoolManager : public IPoolManager
+{
+public:
+    /** Default Constructor */
+    PoolManager();
+    /** Prevent instances of this class to be copy constructed */
+    PoolManager(const PoolManager &) = delete;
+    /** Prevent instances of this class to be copied */
+    PoolManager &operator=(const PoolManager &) = delete;
+    /** Allow instances of this class to be move constructed */
+    PoolManager(PoolManager &&) = default;
+    /** Allow instances of this class to be moved */
+    PoolManager &operator=(PoolManager &&) = default;
+
+    // Inherited methods overridden:
+    IMemoryPool *lock_pool() override;
+    void unlock_pool(IMemoryPool *pool) override;
+    void register_pool(std::unique_ptr<IMemoryPool> pool) override;
+
+private:
+    std::list<std::unique_ptr<IMemoryPool>> _free_pools;     /**< List of free pools */
+    std::list<std::unique_ptr<IMemoryPool>> _occupied_pools; /**< List of occupied pools */
+    std::unique_ptr<arm_compute::Semaphore> _sem;            /**< Semaphore to control the queues */
+    arm_compute::Mutex                      _mtx;            /**< Mutex to control access to the queues */
+};
+} // arm_compute
+#endif /*__ARM_COMPUTE_POOLMANAGER_H__ */
diff --git a/arm_compute/runtime/TensorAllocator.h b/arm_compute/runtime/TensorAllocator.h
index 450323b..40704c0 100644
--- a/arm_compute/runtime/TensorAllocator.h
+++ b/arm_compute/runtime/TensorAllocator.h
@@ -34,13 +34,27 @@
 {
 class Coordinates;
 class TensorInfo;
+class Tensor;
+template <typename>
+class MemoryGroupBase;
+using MemoryGroup = MemoryGroupBase<Tensor>;
 
 /** Basic implementation of a CPU memory tensor allocator. */
 class TensorAllocator : public ITensorAllocator
 {
 public:
     /** Default constructor. */
-    TensorAllocator();
+    TensorAllocator(Tensor *owner = nullptr);
+    /** Default destructor */
+    ~TensorAllocator();
+    /** Prevent instances of this class from being copied (As this class contains pointers). */
+    TensorAllocator(const TensorAllocator &) = delete;
+    /** Prevent instances of this class from being copy assigned (As this class contains pointers). */
+    TensorAllocator &operator=(const TensorAllocator &) = delete;
+    /** Allow instances of this class to be moved */
+    TensorAllocator(TensorAllocator &&) noexcept;
+    /** Allow instances of this class to be moved */
+    TensorAllocator &operator=(TensorAllocator &&) noexcept;
 
     /** Make ITensorAllocator's init methods available */
     using ITensorAllocator::init;
@@ -72,6 +86,11 @@
      *
      */
     void free() override;
+    /** Associates the tensor with a memory group
+     *
+     * @param[in] associated_memory_group Memory group to associate the tensor with
+     */
+    void set_associated_memory_group(MemoryGroup *associated_memory_group);
 
 protected:
     /** No-op for CPU memory
@@ -84,7 +103,9 @@
     void unlock() override;
 
 private:
-    std::shared_ptr<std::vector<uint8_t>> _buffer; /**< CPU memory allocation. */
+    MemoryGroup *_associated_memory_group; /**< Registered memory manager */
+    uint8_t     *_buffer;                  /**< CPU memory allocation. */
+    Tensor      *_owner;                   /**< Owner of the allocator */
 };
 }
 #endif /* __ARM_COMPUTE_TENSORALLOCATOR_H__ */
diff --git a/arm_compute/runtime/Types.h b/arm_compute/runtime/Types.h
new file mode 100644
index 0000000..9916e6d
--- /dev/null
+++ b/arm_compute/runtime/Types.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_RUNTIME_TYPES_H__
+#define __ARM_COMPUTE_RUNTIME_TYPES_H__
+
+#include <map>
+
+namespace arm_compute
+{
+/** Mapping type */
+enum class MappingType
+{
+    BLOBS,  /**< Mappings are in blob granularity */
+    OFFSETS /**< Mappings are in offset granularity in the same blob */
+};
+
+/** A map of (handle, index/offset), where handle is the memory handle of the object
+ * to provide the memory for and index/offset is the buffer/offset from the pool that should be used
+ *
+ * @note All objects are pre-pinned to specific buffers to avoid any relevant overheads
+ */
+using MemoryMappings = std::map<void **, size_t>;
+
+/** A map of the groups and memory mappings */
+using GroupMappings = std::map<size_t, MemoryMappings>;
+
+} // arm_compute
+#endif /* __ARM_COMPUTE_RUNTIME_TYPES_H__ */