arm_compute v18.05
diff --git a/arm_compute/graph/CL/CLMap.h b/arm_compute/graph/CL/CLMap.h
deleted file mode 100644
index 732a1df..0000000
--- a/arm_compute/graph/CL/CLMap.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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_GRAPH_CLMAP_H__
-#define __ARM_COMPUTE_GRAPH_CLMAP_H__
-
-#include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
-
-namespace arm_compute
-{
-class ICLTensor;
-
-namespace graph
-{
-class ITensorObject;
-/** OpenCL map function */
-class CLMap : public arm_compute::IFunction
-{
-public:
-    /** Constructor
-     *
-     * @param[in] tensor   Tensor to map
-     * @param[in] blocking Flag to specify if the map should be blocking or not (defaults to false)
-     */
-    CLMap(ITensorObject *tensor, bool blocking = false);
-    /** Prevent instances from being copy constructed */
-    CLMap(const CLMap &) = delete;
-    /** Prevent instances from being copy assigned */
-    const CLMap &operator=(const CLMap &) = delete;
-    /** Allow instances to be move constructed */
-    CLMap(CLMap &&) = default;
-    /** Allow instances to be move assigned */
-    CLMap &operator=(CLMap &&) = default;
-
-    // Inherited methods overriden:
-    void run() override;
-
-private:
-    arm_compute::ICLTensor *_tensor;   /**< Tensor */
-    bool                    _blocking; /**< Blocking flag */
-};
-} // namespace graph
-} // namespace arm_compute
-
-#endif /* __ARM_COMPUTE_GRAPH_CLMAP_H__ */
diff --git a/arm_compute/graph/CL/CLUnmap.h b/arm_compute/graph/CL/CLUnmap.h
deleted file mode 100644
index 17745c4..0000000
--- a/arm_compute/graph/CL/CLUnmap.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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_GRAPH_CLUNMAP_H__
-#define __ARM_COMPUTE_GRAPH_CLUNMAP_H__
-
-#include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
-
-namespace arm_compute
-{
-class ICLTensor;
-
-namespace graph
-{
-class ITensorObject;
-/** OpenCL un-map function */
-class CLUnmap : public arm_compute::IFunction
-{
-public:
-    /** Constructor
-     *
-     * @param[in] tensor Tensor to un-map
-     */
-    CLUnmap(ITensorObject *tensor);
-    /** Prevent instances from being copy constructed */
-    CLUnmap(const CLUnmap &) = delete;
-    /** Prevent instances from being copy assigned */
-    const CLUnmap &operator=(const CLUnmap &) = delete;
-    /** Allow instances to be move constructed */
-    CLUnmap(CLUnmap &&) = default;
-    /** Allow instances to be move assigned */
-    CLUnmap &operator=(CLUnmap &&) = default;
-
-    // Inherited methods overriden:
-    void run() override;
-
-private:
-    arm_compute::ICLTensor *_tensor; /**< Tensor */
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_CLUNMAP_H__ */
diff --git a/arm_compute/graph/Edge.h b/arm_compute/graph/Edge.h
new file mode 100644
index 0000000..003b0de
--- /dev/null
+++ b/arm_compute/graph/Edge.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_EDGE_H__
+#define __ARM_COMPUTE_GRAPH_EDGE_H__
+
+#include "arm_compute/graph/INode.h"
+#include "arm_compute/graph/Tensor.h"
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class Graph;
+
+/** Graph Edge */
+class Edge final
+{
+public:
+    /** Default Constructor
+     *
+     * @param[in] id           Edge id
+     * @param[in] producer     Producer node id
+     * @param[in] producer_idx Producer node output index
+     * @param[in] consumer     Consumer node id
+     * @param[in] consumer_idx Consumer node input index
+     * @param[in] tensor       Tensor associated with the edge
+     */
+    Edge(EdgeID id, INode *producer, unsigned int producer_idx, INode *consumer, unsigned int consumer_idx, Tensor *tensor)
+        : _id(id), _producer(producer), _consumer(consumer), _producer_idx(producer_idx), _consumer_idx(consumer_idx), _tensor(tensor)
+
+    {
+    }
+    /** Returns edge id
+     *
+     * @return Edge id
+     */
+    EdgeID id() const
+    {
+        return _id;
+    }
+    /** Returns producer node id
+     *
+     * @return Producer node id
+     */
+    NodeID producer_id() const
+    {
+        return (_producer == nullptr) ? EmptyNodeID : _producer->id();
+    }
+    /** Returns sink node id
+     *
+     * @return Sink node id
+     */
+    NodeID consumer_id() const
+    {
+        return (_consumer == nullptr) ? EmptyNodeID : _consumer->id();
+    }
+    /** Returns producer node
+     *
+     * @return Producer node
+     */
+    INode *producer() const
+    {
+        return _producer;
+    }
+    /** Returns consumer node
+     *
+     * @return Consumer node
+     */
+    INode *consumer() const
+    {
+        return _consumer;
+    }
+    /** Returns the index of the output that produces the result in the producer node
+     *
+     * @return Producer node output index
+     */
+    unsigned int producer_idx() const
+    {
+        return _producer_idx;
+    }
+    /** Returns the index of the input that consumes the result in the consumer node
+     *
+     * @return Consumer node input index
+     */
+    unsigned int consumer_idx() const
+    {
+        return _consumer_idx;
+    }
+    /** Returns the tensor associated with this edge
+     *
+     * @return Tensor id
+     */
+    Tensor *tensor() const
+    {
+        return _tensor;
+    }
+    /** Returns the tensor id associated with this edge
+     *
+     * @return Tensor id
+     */
+    TensorID tensor_id() const
+    {
+        return (_tensor == nullptr) ? NullTensorID : _tensor->id();
+    }
+    /** Bind the edge to another tensor
+     *
+     * @note If tensor is nullptr then nothing happens
+     *
+     * @param[in] tensor Tensor to bind the edge to
+     */
+    void update_bound_tensor(Tensor *tensor)
+    {
+        _tensor = (tensor != nullptr) ? tensor : _tensor;
+    }
+
+private:
+    friend class Graph;
+
+private:
+    EdgeID       _id;
+    INode       *_producer;
+    INode       *_consumer;
+    unsigned int _producer_idx;
+    unsigned int _consumer_idx;
+    Tensor      *_tensor;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_EDGE_H__ */
diff --git a/arm_compute/graph/Error.h b/arm_compute/graph/Error.h
deleted file mode 100644
index 0c8ed26..0000000
--- a/arm_compute/graph/Error.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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_GRAPH_ERROR_H__
-#define __ARM_COMPUTE_GRAPH_ERROR_H__
-
-#include "arm_compute/graph/ITensorObject.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Evaluate if a tensor object is null. If the condition is true then an error message is printed and an exception thrown
- *
- * @param[in] function       Function in which the error occurred.
- * @param[in] file           Name of the file where the error occurred.
- * @param[in] line           Line on which the error occurred.
- * @param[in] tensor_object  Tensor object to evaluate
- * @param[in] tensor_objects (Optional) Further allowed tensor objects.
- */
-template <typename... Ts>
-void error_on_unallocated_tensor_object(const char *function, const char *file, int line,
-                                        const ITensorObject *tensor_object, Ts... tensor_objects)
-{
-    ARM_COMPUTE_UNUSED(function);
-    ARM_COMPUTE_UNUSED(file);
-    ARM_COMPUTE_UNUSED(line);
-    ARM_COMPUTE_UNUSED(tensor_object);
-
-    ARM_COMPUTE_ERROR_ON_LOC(tensor_object == nullptr || tensor_object->tensor() == nullptr, function, file, line);
-
-    const std::array<const ITensorObject *, sizeof...(Ts)> tensor_objects_array{ { std::forward<Ts>(tensor_objects)... } };
-    ARM_COMPUTE_UNUSED(tensor_objects_array);
-
-    ARM_COMPUTE_ERROR_ON_LOC(std::any_of(tensor_objects_array.begin(), tensor_objects_array.end(), [&](const ITensorObject * tensor_obj)
-    {
-        return (tensor_obj == nullptr || tensor_object->tensor() == nullptr);
-    }),
-    function, file, line);
-}
-#define ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(...) ::arm_compute::graph::error_on_unallocated_tensor_object(__func__, __FILE__, __LINE__, __VA_ARGS__)
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_ERROR_H__ */
diff --git a/arm_compute/graph/Graph.h b/arm_compute/graph/Graph.h
index 7213087..16f5f97 100644
--- a/arm_compute/graph/Graph.h
+++ b/arm_compute/graph/Graph.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -24,130 +24,238 @@
 #ifndef __ARM_COMPUTE_GRAPH_GRAPH_H__
 #define __ARM_COMPUTE_GRAPH_GRAPH_H__
 
-#include "arm_compute/core/CL/CLTypes.h"
+#include "arm_compute/graph/Edge.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/SubTensor.h"
 #include "arm_compute/graph/Tensor.h"
 #include "arm_compute/graph/Types.h"
+
+#include "support/Mutex.h"
 #include "support/ToolchainSupport.h"
 
+#include <map>
 #include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
 
 namespace arm_compute
 {
-class IFunction;
-
 namespace graph
 {
-/** Graph class */
+/** Graph class
+ *
+ * Represents a multiple source - multiple sink directed graph
+ */
 class Graph final
 {
 public:
-    /** Constructor */
-    Graph();
-    /** Destructor */
-    ~Graph();
-    /** Prevent instances from being copy constructed */
-    Graph(const Graph &) = delete;
-    /** Prevent instances from being copy assigned */
-    const Graph &operator=(const Graph &) = delete;
-    /** Prevent instances from being move constructed */
-    Graph(Graph &&) = delete;
-    /** Prevent instances from being move assigned */
-    Graph &operator=(Graph &&) = delete;
-    /** Initialize the graph
+    Graph() = default;
+    /** Constructor
      *
-     * @param[in] use_cl_tuner Use the CLTuner if this value is true
+     * @param[in] id   Graph identification number. Can be used to differentiate between graphs. Default value 0
+     * @param[in] name Graph name. Default value empty string
      */
-    void graph_init(const bool use_cl_tuner = false);
-    /** Executes the graph */
-    void run();
+    Graph(GraphID id, std::string name);
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    Graph(const Graph &) = delete;
+    /** Prevent instances of this class from being copy assigned (As this class contains pointers) */
+    Graph &operator=(const Graph &) = delete;
+    /** Allow instances of this class to be moved */
+    Graph(Graph &&) = default;
+    /** Allow instances of this class to be move assigned */
+    Graph &operator=(Graph &&) = default;
     /** Adds a node to the graph
      *
-     * @param[in] node Node to add
-     */
-    void add_node(std::unique_ptr<INode> node);
-    /** Adds a tensor to the graph
+     * @note Models a single output node
      *
-     * @param[in] tensor Tensor to add
-     */
-    void add_tensor_object(std::unique_ptr<ITensorObject> tensor);
-    /** Check if the OpenCL target is available
-     */
-    static bool opencl_is_available();
-    /** Returns the GPU target
-     */
-    static GPUTarget gpu_target();
-    /** Manually sets the output of the current node
+     * @tparam NT Node operation
+     * @tparam Ts Arguments to operation
      *
-     * @param[in] tmp Output info to set
-     */
-    void set_temp(TensorInfo &&tmp);
-
-    /** Returns the graph hints that are currently used
+     * @param args Node arguments
      *
-     * @return Graph hints
+     * @return ID of the node
      */
-    GraphHints &hints();
+    template <typename NT, typename... Ts>
+    NodeID add_node(Ts &&... args);
+    /** Remove the node with the given ID
+     *
+     * @param[in] nid ID of the node to remove
+     *
+     * @return True if the removal took place else false
+     */
+    bool remove_node(NodeID nid);
+    /** Adds a connection between two nodes
+     *
+     * @param[in] source     ID of the source node
+     * @param[in] source_idx Output index of the source node
+     * @param[in] sink       ID of the sink node
+     * @param[in] sink_idx   Input index of the sink node
+     *
+     * @return ID of this connection
+     */
+    EdgeID add_connection(NodeID source, size_t source_idx, NodeID sink, size_t sink_idx);
+    /** Removes an edge (connection)
+     *
+     * @param[in] eid Connection to remove
+     *
+     * @return True if the removal took place else false
+     */
+    bool remove_connection(EdgeID eid);
+    /** Returns graph name
+     *
+     * @return Graph name
+     */
+    std::string name() const;
+    /** Returns graph id
+     *
+     * @return Graph id
+     */
+    GraphID id() const;
+    /** Returns graph input nodes
+     *
+     * @return vector containing the graph inputs
+     */
+    const std::vector<NodeID> &inputs();
+    /** Returns nodes of graph
+     *
+     * @warning Nodes can be nullptr if they have been removed during the mutation steps of the graph
+     *
+     * @return Nodes of graph
+     */
+    std::vector<std::unique_ptr<INode>> &nodes();
+    /** Returns nodes of graph
+     *
+     * @warning Nodes can be nullptr if they have been removed during the mutation steps of the graph
+     *
+     * @return Nodes of graph
+     */
+    const std::vector<std::unique_ptr<INode>> &nodes() const;
+    /** Returns edges of graph
+     *
+     * @warning Edges can be nullptr if they have been removed during the mutation steps of the graph
+     *
+     * @return Edges of graph
+     */
+    const std::vector<std::unique_ptr<Edge>> &edges() const;
+    /** Returns tensors of graph
+     *
+     * @warning Tensor can be nullptr if they have been removed during the mutation steps of the graph
+     *
+     * @return Tensors of graph
+     */
+    std::vector<std::unique_ptr<Tensor>> &tensors();
+    /** Returns tensors of graph
+     *
+     * @warning Tensor can be nullptr if they have been removed during the mutation steps of the graph
+     *
+     * @return Tensors of graph
+     */
+    const std::vector<std::unique_ptr<Tensor>> &tensors() const;
+    /** Get node object given its id
+     *
+     * @warning Can be nullptr if node was removed during the mutation steps of the graph
+     *
+     * @param[in] id Node ID
+     *
+     * @return The actual node object
+     */
+    const INode *node(NodeID id) const;
+    /** Get node object given its id
+     *
+     * @warning Can be nullptr if node was removed during the mutation steps of the graph
+     *
+     * @param[in] id Node ID
+     *
+     * @return The actual node object
+     */
+    INode *node(NodeID id);
+    /** Get edge object given its id
+     *
+     * @warning Can be nullptr if node was removed during the mutation steps of the graph
+     *
+     * @param[in] id Edge ID
+     *
+     * @return The actual edge object
+     */
+    const Edge *edge(EdgeID id) const;
+    /** Get edge object given its id
+     *
+     * @warning Can be nullptr if node was removed during the mutation steps of the graph
+     *
+     * @param[in] id Edge ID
+     *
+     * @return The actual edge object
+     */
+    Edge *edge(EdgeID id);
+    /** Get tensor object given its id
+     *
+     * @warning Can be nullptr if tensor was removed during the mutation steps of the graph
+     *
+     * @param[in] id Tensor ID
+     *
+     * @return The actual tensor object
+     */
+    const Tensor *tensor(TensorID id) const;
+    /** Get tensor object given its id
+     *
+     * @warning Can be nullptr if tensor was removed during the mutation steps of the graph
+     *
+     * @param[in] id Tensor ID
+     *
+     * @return The actual tensor object
+     */
+    Tensor *tensor(TensorID id);
 
 private:
-    class Private;
-    std::unique_ptr<Private> _pimpl; /**< Internal implementation class */
+    /** Creates a tensor object
+     *
+     * @param[in] desc Tensor descriptor
+     *
+     * @return Tensor ID
+     */
+    TensorID create_tensor(TensorDescriptor desc = TensorDescriptor());
+
+private:
+    GraphID                              _id      = GraphID(0); /**< Graph id */
+    std::string                          _name    = {};         /**< Graph name */
+    std::vector<std::unique_ptr<INode>>  _nodes   = {};         /**< Graph nodes */
+    std::vector<std::unique_ptr<Edge>>   _edges   = {};         /**< Graph edges */
+    std::vector<std::unique_ptr<Tensor>> _tensors = {};         /**< Graph tensors */
+    std::map<NodeType, std::vector<NodeID>> _tagged_nodes = {}; /**< Graph nodes map with the node type as key */
+    arm_compute::Mutex _mtx = {};                               /**< Mutex used for graph construction */
 };
 
-/** Overloaded stream operator to add a tensor through its tensor info to the graph
- *
- * @param[in, out] graph Graph to add the tensor
- * @param[in]      info  Tensor information of the tensor to be added
- *
- * @return Updated graph
- */
-Graph &operator<<(Graph &graph, TensorInfo &&info);
-/** Overloaded stream operator to add a tensor to the graph
- *
- * @param[in, out] graph  Graph to add the tensor
- * @param[in]      tensor Tensor to be added
- *
- * @return Updated graph
- */
-Graph &operator<<(Graph &graph, Tensor &&tensor);
-/** Overloaded stream operator to add a sub-tensor to the graph
- *
- * @param[in, out] graph      Graph to add the tensor
- * @param[in]      sub_tensor Sub-tensor to be added
- *
- * @return Updated graph
- */
-Graph &operator<<(Graph &graph, SubTensor &&sub_tensor);
-/** Overloaded stream operator to provide a target hint to the graph
- *
- * @param[in, out] graph       Graph to provide the hint to
- * @param[in]      target_hint Target hint to be considered
- *
- * @return Updated graph
- */
-Graph &operator<<(Graph &graph, TargetHint target_hint);
-/** Overloaded stream operator to provide a convolution method hint to the graph
- *
- * @param[in, out] graph            Graph to provide the hint to
- * @param[in]      conv_method_hint Convolution method hint to be considered
- *
- * @return Updated graph
- */
-Graph &operator<<(Graph &graph, ConvolutionMethodHint conv_method_hint);
-/** Overloaded stream operator to add a node to the graph
- *
- * @param[in, out] graph Graph to add the tensor
- * @param[in]      node  Node to be added
- *
- * @return Updated graph
- */
-template <typename Node>
-Graph &operator<<(Graph &graph, Node node)
+template <typename NT, typename... Ts>
+inline NodeID Graph::add_node(Ts &&... args)
 {
-    graph.add_node(arm_compute::support::cpp14::make_unique<Node>(std::move(node)));
-    return graph;
+    std::lock_guard<arm_compute::Mutex> lock(_mtx);
+
+    // Create node
+    NodeID nid  = _nodes.size();
+    auto   node = support::cpp14::make_unique<NT>(std::forward<Ts>(args)...);
+    node->set_graph(this);
+    node->set_id(nid);
+
+    // Keep track of input nodes
+    if(node->type() == NodeType::Input)
+    {
+        _tagged_nodes[NodeType::Input].push_back(nid);
+    }
+
+    // Associate a new tensor with each output
+    for(auto &output : node->_outputs)
+    {
+        output = create_tensor();
+    }
+
+    // Propagate node shape if possible
+    node->forward_descriptors();
+
+    // Add node to the graph nodes
+    _nodes.push_back(std::move(node));
+
+    return nid;
 }
 } // namespace graph
 } // namespace arm_compute
diff --git a/arm_compute/graph/GraphBuilder.h b/arm_compute/graph/GraphBuilder.h
new file mode 100644
index 0000000..303e2f8
--- /dev/null
+++ b/arm_compute/graph/GraphBuilder.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_GRAPH_BUILDER_H__
+#define __ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H__
+
+#include "arm_compute/graph/ITensorAccessor.h"
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declaration
+class Graph;
+
+/** Graph builder class
+ *
+ * Builds and compiles a graph
+ */
+class GraphBuilder final
+{
+public:
+    /** Adds a Const node to the graph
+     *
+     * @param[in] g        Graph to add the node to
+     * @param[in] params   Common node parameters
+     * @param[in] desc     Tensor descriptor of the node
+     * @param[in] accessor (Optional) Accessor of the const node data
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_const_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor = nullptr);
+    /** Adds an input layer node to the graph
+     *
+     * @param[in] g        Graph to add the node to
+     * @param[in] params   Common node parameters
+     * @param[in] desc     Tensor descriptor of the Tensor
+     * @param[in] accessor (Optional) Accessor of the input node data
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_input_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor = nullptr);
+    /** Adds an output layer node to the graph
+     *
+     * @param[in] g        Graph to add the node to
+     * @param[in] params   Common node parameters
+     * @param[in] input    Input to the output node as a NodeID-Index pair
+     * @param[in] accessor (Optional) Accessor of the output node data
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor = nullptr);
+    /** Adds an activation layer node to the graph
+     *
+     * @param[in] g        Graph to add the node to
+     * @param[in] params   Common node parameters
+     * @param[in] input    Input to the activation layer node as a NodeID-Index pair
+     * @param[in] act_info Activation layer information
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_activation_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info);
+    /** Adds a batch normalization layer node to the graph
+     *
+     * @param[in] g              Graph to add the node to
+     * @param[in] params         Common node parameters
+     * @param[in] input          Input to the batch normalization layer node as a NodeID-Index pair
+     * @param[in] epsilon        Epsilon parameter
+     * @param[in] mean_accessor  Const Node ID that contains the mean values
+     * @param[in] var_accessor   Const Node ID that contains the variance values
+     * @param[in] beta_accessor  Const Node ID that contains the beta values. Can be EmptyNodeID
+     * @param[in] gamma_accessor Const Node ID that contains the gamma values. Can be EmptyNodeID
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_batch_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, float epsilon,
+                                               ITensorAccessorUPtr mean_accessor = nullptr, ITensorAccessorUPtr var_accessor = nullptr,
+                                               ITensorAccessorUPtr beta_accessor = nullptr, ITensorAccessorUPtr gamma_accessor = nullptr);
+    /** Adds a convolution layer node to the graph
+     *
+     * @param[in] g                     Graph to add the node to
+     * @param[in] params                Common node parameters
+     * @param[in] input                 Input to the convolution layer node as a NodeID-Index pair
+     * @param[in] kernel_spatial_extend Spatial extend of convolution kernels
+     * @param[in] depth                 Number of convolution kernels
+     * @param[in] conv_info             Convolution layer information
+     * @param[in] num_groups            (Optional) Number of groups for a grouped convolution. Defaults to 1
+     * @param[in] method                (Optional) Convolution method to use
+     * @param[in] fast_math_hint        (Optional) Fast math hint
+     * @param[in] weights_accessor      (Optional) Accessor of the weights node data
+     * @param[in] bias_accessor         (Optional) Accessor of the bias node data
+     * @param[in] weights_quant_info    (Optional) Weights quantization info
+     * @param[in] out_quant_info        (Optional) Output quantization info
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_convolution_node(Graph &g, NodeParams params, NodeIdxPair input,
+                                       Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo conv_info,
+                                       unsigned int num_groups = 1, ConvolutionMethod method = ConvolutionMethod::DEFAULT, FastMathHint fast_math_hint = FastMathHint::DISABLED,
+                                       ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr,
+                                       const QuantizationInfo weights_quant_info = QuantizationInfo(),
+                                       const QuantizationInfo out_quant_info     = QuantizationInfo());
+    /** Adds a depth concatenate node to the graph
+     *
+     * @param[in] g      Graph to add the node to
+     * @param[in] params Common node parameters
+     * @param[in] inputs Inputs to the depth concatenate layer node as a NodeID-Index pair
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_depth_concatenate_node(Graph &g, NodeParams params, std::vector<NodeIdxPair> inputs);
+    /** Adds a depth-wise convolution layer node to the graph
+     *
+     * @param[in] g                     Graph to add the node to
+     * @param[in] params                Common node parameters
+     * @param[in] input                 Input to the depthwise convolution layer node as a NodeID-Index pair
+     * @param[in] kernel_spatial_extend Spatial extend of convolution kernels
+     * @param[in] conv_info             Convolution layer information
+     * @param[in] method                (Optional) Convolution method to use
+     * @param[in] weights_accessor      (Optional) Accessor of the weights node data
+     * @param[in] bias_accessor         (Optional) Accessor of the bias node data
+     * @param[in] quant_info            (Optional) Weights quantization info
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_depthwise_convolution_node(Graph &g, NodeParams params, NodeIdxPair input,
+                                                 Size2D kernel_spatial_extend, PadStrideInfo conv_info,
+                                                 DepthwiseConvolutionMethod method    = DepthwiseConvolutionMethod::DEFAULT,
+                                                 ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr, const QuantizationInfo quant_info = QuantizationInfo());
+    /** Adds an element-wise layer node to the graph
+     *
+     * @param[in] g         Graph to add the node to
+     * @param[in] params    Common node parameters
+     * @param[in] input0    First input to the element-wise operation layer node as a NodeID-Index pair
+     * @param[in] input1    Second input to the element-wise operation layer node as a NodeID-Index pair
+     * @param[in] operation Element-wise operation to perform
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_elementwise_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation);
+    /** Adds a flatten layer node to the graph
+     *
+     * @param[in] g      Graph to add the node to
+     * @param[in] params Common node parameters
+     * @param[in] input  Input to the flatten layer node as a NodeID-Index pair
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_flatten_node(Graph &g, NodeParams params, NodeIdxPair input);
+    /** Adds a fully connected layer node to the graph
+     *
+     * @param[in] g                Graph to add the layer to
+     * @param[in] params           Common node parameters
+     * @param[in] input            Input to the fully connected layer node as a NodeID-Index pair
+     * @param[in] num_outputs      Number of output neurons
+     * @param[in] weights_accessor (Optional) Accessor of the weights node data
+     * @param[in] bias_accessor    (Optional) Accessor of the bias node data
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs,
+                                            ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr);
+    /** Adds a normalization layer node to the graph
+     *
+     * @param[in] g         Graph to add the node to
+     * @param[in] params    Common node parameters
+     * @param[in] input     Input to the normalization layer node as a NodeID-Index pair
+     * @param[in] norm_info Normalization layer information
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info);
+    /** Adds a pooling layer node to the graph
+     *
+     * @param[in] g         Graph to add the node to
+     * @param[in] params    Common node parameters
+     * @param[in] input     Input to the pooling layer node as a NodeID-Index pair
+     * @param[in] pool_info Pooling layer information
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_pooling_node(Graph &g, NodeParams params, NodeIdxPair input, PoolingLayerInfo pool_info);
+    /** Adds a reshape layer node to the graph
+     *
+     * @param[in] g      Graph to add the node to
+     * @param[in] params Common node parameters
+     * @param[in] input  Input to the reshape layer node as a NodeID-Index pair
+     * @param[in] shape  Output reshaped shape
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_reshape_node(Graph &g, NodeParams params, NodeIdxPair input, TensorShape shape);
+    /** Adds a scale layer node to the graph
+     * This layer computes a product of the input with a scale (read from mul_accessor) and it applies an offset (read from add_accessor).
+     * output = input * mul_w + add_w
+     *
+     * @param[in] g            Graph to add the layer to
+     * @param[in] params       Common node parameters
+     * @param[in] input        Input to the fully connected layer node as a NodeID-Index pair
+     * @param[in] mul_accessor (Optional) Accessor of the mul node data
+     * @param[in] add_accessor (Optional) Accessor of the add node data
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_scale_layer(Graph &g, const NodeParams &params, NodeIdxPair input,
+                                  ITensorAccessorUPtr mul_accessor = nullptr, ITensorAccessorUPtr add_accessor = nullptr);
+    /** Adds a softmax node to the graph
+     *
+     * @param[in] g      Graph to add the node to
+     * @param[in] params Common node parameters
+     * @param[in] input  Input to the softmax layer node as a NodeID-Index pair
+     * @param[in] beta   Beta parameter
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_softmax_node(Graph &g, NodeParams params, NodeIdxPair input, float beta = 1.f);
+    /** Adds a split node to the graph
+     *
+     * @param[in] g          Graph to add the node to
+     * @param[in] params     Common node parameters
+     * @param[in] input      Input to the split layer node as a NodeID-Index pair
+     * @param[in] num_splits Number of different splits
+     * @param[in] axis       (Optional) Split axis. Defaults to 0
+     *
+     * @return Node ID of the created node, EmptyNodeID in case of error
+     */
+    static NodeID add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis = 0);
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H__ */
diff --git a/arm_compute/graph/GraphContext.h b/arm_compute/graph/GraphContext.h
index 98bc8c0..1831cc2 100644
--- a/arm_compute/graph/GraphContext.h
+++ b/arm_compute/graph/GraphContext.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,68 +21,81 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_CONTEXT_H__
-#define __ARM_COMPUTE_GRAPH_CONTEXT_H__
+#ifndef __ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H__
+#define __ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H__
 
 #include "arm_compute/graph/Types.h"
 
+#include "arm_compute/runtime/IMemoryManager.h"
+
+#include <map>
+#include <memory>
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Hints that can be passed to the graph to expose parameterization */
-class GraphHints
+/** Contains structs required for memory management */
+struct MemoryManagerContext
 {
-public:
-    /** Default Constructor */
-    GraphHints(TargetHint            target_hint      = TargetHint::DONT_CARE,
-               ConvolutionMethodHint conv_method_hint = ConvolutionMethodHint::GEMM);
-    /** Sets target execution hint
-     *
-     * @param target_hint Target execution hint
-     */
-    void set_target_hint(TargetHint target_hint);
-    /** Sets convolution method to use
-     *
-     * @param convolution_method Convolution method to use
-     */
-    void set_convolution_method_hint(ConvolutionMethodHint convolution_method);
-    /** Returns target execution hint
-     *
-     * @return target execution hint
-     */
-    TargetHint target_hint() const;
-    /** Returns convolution method hint
-     *
-     * @return convolution method hint
-     */
-    ConvolutionMethodHint convolution_method_hint() const;
-
-private:
-    TargetHint            _target_hint;             /**< Target execution hint */
-    ConvolutionMethodHint _convolution_method_hint; /**< Convolution method hint */
+    Target                                       target      = { Target::UNSPECIFIED }; /**< Target */
+    std::shared_ptr<arm_compute::IMemoryManager> intra_mm    = { nullptr };             /**< Intra-function memory manager */
+    std::shared_ptr<arm_compute::IMemoryManager> cross_mm    = { nullptr };             /**< Cross-function memory manager */
+    std::shared_ptr<arm_compute::IMemoryGroup>   cross_group = { nullptr };             /**< Cross-function memory group */
 };
 
-/** Graph context */
-class GraphContext
+/** Graph context **/
+class GraphContext final
 {
 public:
-    /** Default Constuctor */
+    /** Constructor */
     GraphContext();
-    /** Returns graph hints
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    GraphContext(const GraphContext &) = delete;
+    /** Default move constructor */
+    GraphContext(GraphContext &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    GraphContext &operator=(const GraphContext &) = delete;
+    /** Default move assignment operator */
+    GraphContext &operator=(GraphContext &&) = default;
+    /** Graph configuration accessor
      *
-     * @return Graph hints
-     */
-    GraphHints &hints();
-    /** Returns graph hints
+     * @note Every alteration has to be done before graph finalization
      *
-     * @return Graph hints
+     * @return The graph configuration
      */
-    const GraphHints &hints() const;
+    const GraphConfig &config() const;
+    /** Sets graph configuration
+     *
+     * @param[in] config Configuration to use
+     */
+    void set_config(const GraphConfig &config);
+    /** Inserts a memory manager context
+     *
+     * @param[in] memory_ctx Memory manage context
+     *
+     * @return If the insertion succeeded else false
+     */
+    bool insert_memory_management_ctx(MemoryManagerContext &&memory_ctx);
+    /** Gets a memory manager context for a given target
+     *
+     * @param[in] target To retrieve the management context
+     *
+     * @return Management context for the target if exists else nullptr
+     */
+    MemoryManagerContext *memory_management_ctx(Target target);
+    /** Gets the memory managers map
+     *
+     * @return Memory manager contexts
+     */
+    std::map<Target, MemoryManagerContext> &memory_managers();
+    /** Finalizes memory managers in graph context */
+    void finalize();
 
 private:
-    GraphHints _hints; /**< Graph hints */
+    GraphConfig _config;                                     /**< Graph configuration */
+    std::map<Target, MemoryManagerContext> _memory_managers; /**< Memory managers for each target */
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_CONTEXT_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H__ */
diff --git a/arm_compute/graph/GraphManager.h b/arm_compute/graph/GraphManager.h
new file mode 100644
index 0000000..9526a0b
--- /dev/null
+++ b/arm_compute/graph/GraphManager.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_GRAPH_MANAGER_H__
+#define __ARM_COMPUTE_GRAPH_GRAPH_MANAGER_H__
+
+#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/Workload.h"
+
+#include <map>
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declaration
+class Graph;
+class GraphContext;
+class PassManager;
+
+/** Graph manager class
+ *
+ * Manages a list of graphs along with their resources
+ */
+class GraphManager final
+{
+public:
+    /** Default Constructor **/
+    GraphManager();
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    GraphManager(const GraphManager &) = delete;
+    /** Default move constructor */
+    GraphManager(GraphManager &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    GraphManager &operator=(const GraphManager &) = delete;
+    /** Default move assignment operator */
+    GraphManager &operator=(GraphManager &&) = default;
+    /** Finalizes a given graph
+     *
+     * @warning At this given time finalize_graph will alter the passed graph,
+     *          plan is to avoid by copying the graph structure,
+     *          or provide another entry-point for this functionality as it will increase the memory requirements
+     *
+     * @param[in] graph  Graph to finalize
+     * @param[in] ctx    Graph context
+     * @param[in] pm     Pass manager to use for any optimization passes
+     * @param[in] target Execution target (Single target execution is currently supported)
+     */
+    void finalize_graph(Graph &graph, GraphContext &ctx, PassManager &pm, Target target);
+    /** Executes a graph
+     *
+     * @param[in] graph Graph to execute
+     */
+    void execute_graph(Graph &graph);
+    /** Invalidates the graph execution workload
+     *
+     * @param[in] graph Graph to invalidate
+     */
+    void invalidate_graph(Graph &graph);
+
+private:
+    std::map<GraphID, ExecutionWorkload> _workloads = {}; /**< Graph workloads */
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_GRAPH_MANAGER_H__ */
diff --git a/arm_compute/graph/IDeviceBackend.h b/arm_compute/graph/IDeviceBackend.h
new file mode 100644
index 0000000..f28cb1a
--- /dev/null
+++ b/arm_compute/graph/IDeviceBackend.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_IDEVICEBACKEND_H__
+#define __ARM_COMPUTE_GRAPH_IDEVICEBACKEND_H__
+
+#include "arm_compute/graph/ITensorHandle.h"
+#include "arm_compute/graph/Types.h"
+#include "arm_compute/runtime/IFunction.h"
+#include "arm_compute/runtime/IMemoryManager.h"
+
+#include <memory>
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class Graph;
+class GraphContext;
+class Tensor;
+class INode;
+
+namespace backends
+{
+/** Device backend interface */
+class IDeviceBackend
+{
+public:
+    /** Virtual Destructor */
+    virtual ~IDeviceBackend() = default;
+    /** Initializes the backend */
+    virtual void initialize_backend() = 0;
+    /** Setups the given graph context
+     *
+     * @param[in] ctx Graph context
+     */
+    virtual void setup_backend_context(GraphContext &ctx) = 0;
+    /** Checks if an instantiated backend is actually supported
+     *
+     * @return True if the backend is supported else false
+     */
+    virtual bool is_backend_supported() = 0;
+    /** Gets a backend memory allocator
+     *
+     * @return Backend memory allocator
+     */
+    virtual IAllocator *backend_allocator() = 0;
+    /** Create a backend Tensor
+     *
+     * @param[in] tensor The tensor we want to create a backend tensor for
+     *
+     * @return Backend tensor handle
+     */
+    virtual std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) = 0;
+    /** Create a backend Sub-Tensor
+     *
+     * @param[in] parent        Parent sub-tensor handle
+     * @param[in] shape         Shape of the sub-tensor
+     * @param[in] coords        Starting coordinates of the sub-tensor
+     * @param[in] extend_parent Extends parent shape if true
+     *
+     * @return Backend sub-tensor handle
+     */
+    virtual std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) = 0;
+    /** Configure a backend Node
+     *
+     * @note This creates an appropriate configured backend function for the given node
+     *
+     * @param[in] node The node we want to configure
+     * @param[in] ctx  Context to use
+     *
+     * @return Backend execution function
+     */
+    virtual std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) = 0;
+    /** Validate a node
+     *
+     * @param[in] node The node we want to validate
+     *
+     * @return An error status
+     */
+    virtual Status validate_node(INode &node) = 0;
+    /** Create a backend memory manager given its affinity
+     *
+     * @param[in] affinity Memory Manager affinity
+     *
+     * @return Memory manager
+     */
+    virtual std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) = 0;
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif //__ARM_COMPUTE_GRAPH_IDEVICEBACKEND_H__
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/IGraphMutator.h
similarity index 66%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/IGraphMutator.h
index b5d1bc5..714fd7c 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/IGraphMutator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,33 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_IGRAPHMUTATOR_H__
+#define __ARM_COMPUTE_GRAPH_IGRAPHMUTATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+// Forward declarations
+class Graph;
+
+/** Graph mutator interface */
+class IGraphMutator
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Virtual Destructor */
+    virtual ~IGraphMutator() = default;
+    /** Walk the graph and perform a specific mutation
+     *
+     * @param[in, out] g Graph to walk and mutate
+     */
+    virtual void mutate(Graph &g) = 0;
+    /** Returns mutator name
+     *
+     * @return Mutator name
+     */
+    virtual const char *name() = 0;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_IGRAPHMUTATOR_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/IGraphPrinter.h
similarity index 67%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/IGraphPrinter.h
index b5d1bc5..aba52b1 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/IGraphPrinter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,31 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__
+#define __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include <ostream>
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+// Forward declarations
+class Graph;
+
+/** Graph printer interface */
+class IGraphPrinter
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Virtual Destructor */
+    virtual ~IGraphPrinter() = default;
+    /** Print graph
+     *
+     * @param[in]  g  Graph to print
+     * @param[out] os Output stream
+     */
+    virtual void print(const Graph &g, std::ostream &os) = 0;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__ */
diff --git a/arm_compute/graph/INode.h b/arm_compute/graph/INode.h
index 1969423..f8101d7 100644
--- a/arm_compute/graph/INode.h
+++ b/arm_compute/graph/INode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -24,63 +24,228 @@
 #ifndef __ARM_COMPUTE_GRAPH_INODE_H__
 #define __ARM_COMPUTE_GRAPH_INODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/ITensorObject.h"
+#include "arm_compute/core/Error.h"
+#include "arm_compute/graph/TensorDescriptor.h"
 #include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
 
-#include <memory>
+#include <set>
 
 namespace arm_compute
 {
 namespace graph
 {
+// Forward declarations
+class Graph;
+class Edge;
+class INodeVisitor;
+class Tensor;
+
 /** Node interface */
 class INode
 {
 public:
-    /** Virtual Destructor */
+    /** Constructor */
+    INode();
+    /** Destructor **/
     virtual ~INode() = default;
-    /** Interface to be implemented that instantiates the node
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    INode(const INode &) = delete;
+    /** Prevent instances of this class from being copy assigned (As this class contains pointers) */
+    INode &operator=(const INode &) = delete;
+    /** Allow instances of this class to be moved */
+    INode(INode &&) = default;
+    /** Allow instances of this class to be move assigned */
+    INode &operator=(INode &&) = default;
+    /** Validate node
      *
-     * @param[in] ctx    Graph context to be used
-     * @param[in] input  Input tensor of the node
-     * @param[in] output Output tensor of the node
+     * @return Status containing any errors
      */
-    virtual std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) = 0;
-    /** Override the existing target hint
+    virtual Status validate() const;
+    /** Returns node's type
      *
-     * @note If the input is DONT_CARE then the method has to pick a technology,
-     *       else it can accept the hint or override it (But not with DONT_CARE)
-     *
-     * @param[in] target_hint Target hint to be considered
-     *
-     * @return The updated target hint
+     * @return Node's type
      */
-    TargetHint override_target_hint(TargetHint target_hint) const;
-    /** Method to check if the node supports in-place operations.
+    virtual NodeType type() const = 0;
+    /** Accepts a node visitor
      *
-     * @return True if the node supports in-place operations, false otherwise.
+     * @param[in] v Visitor to accept
      */
-    virtual bool supports_in_place() const;
-    /** Set the value of the _supports_in_place attribute.
+    virtual void accept(INodeVisitor &v) = 0;
+    /** Forwards descriptor information to outputs if possible
      *
-     * @param[in] value Boolean value to assign to _supports_in_place.
+     * @return True if descriptor information could be forwarded otherwise false
      */
-    void set_supports_in_place(bool value);
+    virtual bool forward_descriptors() = 0;
+    /** Calculates output configuration
+     *
+     * @param[in] idx Output index to configure
+     *
+     * @return Output descriptor configuration
+     */
+    virtual TensorDescriptor configure_output(size_t idx) const = 0;
+    /** Returns node's name
+     *
+     * @return Node name
+     */
+    std::string name() const;
+    /** Returns node's ID
+     *
+     * @return Node's ID
+     */
+    NodeID id() const;
+    /** Returns node's Graph
+     *
+     * @return Node's graph
+     */
+    const Graph *graph() const;
+    /** Returns node's Graph
+     *
+     * @return Node's graph
+     */
+    Graph *graph();
+    /** Sets the graph that this node is registered to
+     *
+     * @param[in] g Back reference to graph
+     */
+    void set_graph(Graph *g);
+    /** Sets the node id
+     *
+     * @param[in] id Node id
+     */
+    void set_id(NodeID id);
+    /** Sets common node parameters
+     *
+     * @param[in] common_params Common node parameters to set
+     */
+    void set_common_node_parameters(NodeParams common_params);
+    /** Sets target preference
+     *
+     * @note This is not the target that the graph executor might choose, its just an indication
+     *
+     * @param[in] target Target preference
+     */
+    void set_requested_target(Target target);
+    /** Sets the final execution target
+     *
+     * @note GraphManager might change this target
+     *
+     * @param[in] target Final execution target
+     */
+    void set_assigned_target(Target target);
+    /** Sets the output tensor of at a given index
+     *
+     * @note All edges will get updated
+     *
+     * @param[in] tid Tensor ID
+     * @param[in] idx Output index
+     */
+    void set_output_tensor(TensorID tid, size_t idx);
+    /** Returns inputs of the node
+     *
+     * @return Inputs of the node
+     */
+    const std::vector<TensorID> &inputs() const;
+    /** Returns outputs of the node
+     *
+     * @return Outputs of the node
+     */
+    const std::vector<TensorID> &outputs() const;
+    /** Returns input edge set
+     *
+     * @return Set of input edges
+     */
+    const std::vector<EdgeID> &input_edges() const;
+    /** Returns output edge set
+     *
+     * @return Set of output edges
+     */
+    const std::set<EdgeID> &output_edges() const;
+    /** Returns the tensor ID of a given input of the node
+     *
+     * @note Precondition : idx should be a valid input index
+     *
+     * @param[in] idx Index of the node input
+     *
+     * @return TensorID of the requested input
+     */
+    TensorID input_id(size_t idx) const;
+    /** Returns the tensor ID of a given output of the node
+     *
+     * @note Precondition : idx should be a valid output index
+     *
+     * @param[in] idx Index of the node output
+     *
+     * @return TensorID of the requested output
+     */
+    TensorID output_id(size_t idx) const;
+    /** Returns the tensor of a given input of the node
+     *
+     * @note Precondition : idx should be a valid input index
+     *
+     * @param[in] idx Index of the node input
+     *
+     * @return Tensor of the requested input
+     */
+    Tensor *input(size_t idx) const;
+    /** Returns the tensor of a given output of the node
+     *
+     * @note Precondition : idx should be a valid output index
+     *
+     * @param[in] idx Index of the node output
+     *
+     * @return Tensor of the requested output
+     */
+    Tensor *output(size_t idx) const;
+    /** Returns the edge ID of a given input of the node
+     *
+     * @note Precondition : idx should be a valid input index
+     *
+     * @param[in] idx Index of the node input
+     *
+     * @return EdgeID of the requested input
+     */
+    EdgeID input_edge_id(size_t idx) const;
+    /** Returns the edge of a given input of the node
+     *
+     * @note Precondition : idx should be a valid input index
+     *
+     * @param[in] idx Index of the node input
+     *
+     * @return Edge of the requested input
+     */
+    Edge *input_edge(size_t idx) const;
+    /** Returns number of inputs of the node
+     *
+     * @return Number of inputs
+     */
+    size_t num_inputs() const;
+    /** Returns number of outputs of the node
+     *
+     * @return Number of outputs
+     */
+    size_t num_outputs() const;
+    /** Returns requested target for this node
+     *
+     * @return Requested execution target
+     */
+    Target requested_target() const;
+    /** Returns assigned target for this node
+     *
+     * @return Assigned target of this node
+     */
+    Target assigned_target() const;
 
 protected:
-    /** Interface to be implement that override the hints
-     *
-     * @param[in] hints Hints to be considered
-     *
-     * @return The updated hints
-     */
-    virtual GraphHints node_override_hints(GraphHints hints) const;
+    friend class Graph;
 
 protected:
-    TargetHint _target_hint{ TargetHint::DONT_CARE };
-    bool       _supports_in_place{ false };
+    Graph                *_graph;           /**< Backward reference to graph owning the node */
+    NodeID                _id;              /**< Node ID */
+    NodeParams            _common_params;   /**< Node common params */
+    std::vector<TensorID> _outputs;         /**< Output of the node */
+    std::vector<EdgeID>   _input_edges;     /**< Inputs edge set */
+    std::set<EdgeID>      _output_edges;    /**< Output edge set */
+    Target                _assigned_target; /**< Assigned target by the Graph executor */
 };
 } // namespace graph
 } // namespace arm_compute
diff --git a/arm_compute/graph/INodeVisitor.h b/arm_compute/graph/INodeVisitor.h
new file mode 100644
index 0000000..b5446c4
--- /dev/null
+++ b/arm_compute/graph/INodeVisitor.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_INODEVISITOR_H__
+#define __ARM_COMPUTE_GRAPH_INODEVISITOR_H__
+
+#include "arm_compute/graph/nodes/NodesFwd.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/**  Node visitor interface */
+class INodeVisitor
+{
+public:
+    /** Default destructor. */
+    virtual ~INodeVisitor() = default;
+    /** Visit INode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(INode &n) = 0;
+    /** Visit ActivationLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(ActivationLayerNode &n) = 0;
+    /** Visit BatchNormalizationLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(BatchNormalizationLayerNode &n) = 0;
+    /** Visit ConstNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(ConstNode &n) = 0;
+    /** Visit ConvolutionLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(ConvolutionLayerNode &n) = 0;
+    /** Visit DepthConcatenateLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(DepthConcatenateLayerNode &n) = 0;
+    /** Visit DepthwiseConvolutionLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(DepthwiseConvolutionLayerNode &n) = 0;
+    /** Visit EltwiseLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(EltwiseLayerNode &n) = 0;
+    /** Visit FlattenLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(FlattenLayerNode &n) = 0;
+    /** Visit FullyConnectedLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(FullyConnectedLayerNode &n) = 0;
+    /** Visit InputNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(InputNode &n) = 0;
+    /** Visit NormalizationLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(NormalizationLayerNode &n) = 0;
+    /** Visit OutputNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(OutputNode &n) = 0;
+    /** Visit PoolingLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(PoolingLayerNode &n) = 0;
+    /** Visit ReshapeLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(ReshapeLayerNode &n) = 0;
+    /** Visit SoftmaxLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(SoftmaxLayerNode &n) = 0;
+    /** Visit SplitLayerNode.
+     *
+     * @param[in] n Node to visit.
+     */
+    virtual void visit(SplitLayerNode &n) = 0;
+};
+
+/** Default visitor implementation
+ *
+ * Implements visit methods by calling a default function.
+ * Inherit from DefaultNodeVisitor if you don't want to provide specific implementation for all nodes.
+ */
+class DefaultNodeVisitor : public INodeVisitor
+{
+public:
+    /** Default destructor */
+    virtual ~DefaultNodeVisitor() = default;
+
+#ifndef DOXYGEN_SKIP_THIS
+    // Inherited methods overridden
+    virtual void visit(INode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(ActivationLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(BatchNormalizationLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(ConstNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(ConvolutionLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(DepthConcatenateLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(DepthwiseConvolutionLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(EltwiseLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(FlattenLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(FullyConnectedLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(InputNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(NormalizationLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(OutputNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(PoolingLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(ReshapeLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(SoftmaxLayerNode &n) override
+    {
+        default_visit();
+    }
+    virtual void visit(SplitLayerNode &n) override
+    {
+        default_visit();
+    }
+#endif /* DOXYGEN_SKIP_THIS */
+
+    /** Function to be overloaded by the client and implement default behavior for the
+     *  non-overloaded visitors
+     */
+    virtual void default_visit() = 0;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_INODEVISITOR_H__ */
diff --git a/arm_compute/graph/IOperation.h b/arm_compute/graph/IOperation.h
deleted file mode 100644
index a9fa4f8..0000000
--- a/arm_compute/graph/IOperation.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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_GRAPH_IOPERATION_H__
-#define __ARM_COMPUTE_GRAPH_IOPERATION_H__
-
-#include "arm_compute/graph/NodeContext.h"
-#include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
-
-#include <memory>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Operation functor interface */
-class IOperation
-{
-public:
-    /** Virtual Destructor */
-    virtual ~IOperation() = default;
-    /** Interface to be implemented that configures an operation
-     *
-     * @param[in] ctx Node parameters to be used by the operation
-     */
-    virtual std::unique_ptr<arm_compute::IFunction> configure(NodeContext &ctx) = 0;
-    /** Interface to be implemented that returns the target of the operation
-     *
-     * @return Target of the operation
-     */
-    virtual TargetHint target() const = 0;
-};
-
-#define REGISTER_SIMPLE_OPERATION(NAME, TARGET, OP)                                \
-    class NAME : public IOperation                                                 \
-    {                                                                              \
-    public:                                                                    \
-        std::unique_ptr<arm_compute::IFunction> configure(NodeContext &ctx) final; \
-        TargetHint target() const final                                            \
-        {                                                                          \
-            return TargetHint::TARGET;                                             \
-        }                                                                          \
-    };                                                                             \
-    static detail::OperationRegistrar<NAME> NAME##_registrar(OP);                  \
-    std::unique_ptr<arm_compute::IFunction> NAME::configure(NodeContext &ctx)
-
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_IOPERATION_H__ */
diff --git a/arm_compute/graph/ITensorAccessor.h b/arm_compute/graph/ITensorAccessor.h
index d6a254a..2df39c2 100644
--- a/arm_compute/graph/ITensorAccessor.h
+++ b/arm_compute/graph/ITensorAccessor.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,10 +21,12 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_ITENSORACCESSOR_H__
-#define __ARM_COMPUTE_GRAPH_ITENSORACCESSOR_H__
+#ifndef __ARM_COMPUTE_GRAPH_ITENSOR_ACCESSOR_H__
+#define __ARM_COMPUTE_GRAPH_ITENSOR_ACCESSOR_H__
 
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/core/ITensor.h"
+
+#include <memory>
 
 namespace arm_compute
 {
@@ -44,6 +46,8 @@
      */
     virtual bool access_tensor(ITensor &tensor) = 0;
 };
+
+using ITensorAccessorUPtr = std::unique_ptr<ITensorAccessor>;
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_ITENSORACCESSOR_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_SUB_STREAM_H__ */
\ No newline at end of file
diff --git a/arm_compute/graph/ITensorHandle.h b/arm_compute/graph/ITensorHandle.h
new file mode 100644
index 0000000..261ebf5
--- /dev/null
+++ b/arm_compute/graph/ITensorHandle.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_ITENSORHANDLE_H__
+#define __ARM_COMPUTE_GRAPH_ITENSORHANDLE_H__
+
+#include "arm_compute/core/ITensor.h"
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+// Forward declarations
+class IMemoryGroup;
+
+namespace graph
+{
+/** Tensor handle interface object */
+class ITensorHandle
+{
+public:
+    /** Default virtual destructor */
+    virtual ~ITensorHandle() = default;
+    /** Allocates backend memory for the handle */
+    virtual void allocate() = 0;
+    /** Allocates backend memory for the handle */
+    virtual void free() = 0;
+    /** Set backend tensor to be managed by a memory group
+     *
+     * @param[in] mg Memory group
+     */
+    virtual void manage(IMemoryGroup *mg) = 0;
+    /** Maps backend tensor object
+     *
+     * @param[in] blocking Flags if the mapping operations should be blocking
+     */
+    virtual void map(bool blocking) = 0;
+    /** Un-maps a backend tensor object */
+    virtual void unmap() = 0;
+    /** Releases backend tensor if is marked as unused
+     *
+     *
+     * @note This has no effect on sub-tensors
+     * @warning Parent tensors don't keep track of sub-tensors,
+     *          thus if a parent is set as unused then all sub-tensors will be invalidated,
+     *          on the other hand if a sub-tensor is marked as unused then the parent tensor won't be released
+     */
+    virtual void release_if_unused() = 0;
+    /** Backend tensor object accessor */
+    virtual arm_compute::ITensor &tensor() = 0;
+    /** Backend tensor object const accessor */
+    virtual const arm_compute::ITensor &tensor() const = 0;
+    /** Return the parent tensor handle if is a subtensor else this
+     *
+     * @return Parent tensor handle
+     */
+    virtual ITensorHandle *parent_handle() = 0;
+    /** Checks if a backing tensor is a sub-tensor object or not
+     *
+     * @return True if the backend tensor is a sub-tensor else false
+     */
+    virtual bool is_subtensor() const = 0;
+    /** Returns target type
+     *
+     * @return Target type
+     */
+    virtual Target target() const = 0;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_ITENSORHANDLE_H__ */
diff --git a/arm_compute/graph/ITensorObject.h b/arm_compute/graph/ITensorObject.h
deleted file mode 100644
index a922dd5..0000000
--- a/arm_compute/graph/ITensorObject.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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_GRAPH_ITENSOROBJECT_H__
-#define __ARM_COMPUTE_GRAPH_ITENSOROBJECT_H__
-
-#include "arm_compute/graph/ITensorAccessor.h"
-#include "arm_compute/graph/Types.h"
-#include "support/ToolchainSupport.h"
-
-#include <memory>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Tensor object interface */
-class ITensorObject
-{
-public:
-    /** Default Destructor */
-    virtual ~ITensorObject() = default;
-    /** Calls accessor on tensor
-     *
-     * @return True if succeeds else false
-     */
-    virtual bool call_accessor() = 0;
-    /** Checks if tensor has an accessor set.
-     *
-     * @return True if an accessor has been set else false
-     */
-    virtual bool has_accessor() const = 0;
-    /** Sets target of the tensor
-     *
-     * @param[in] target Target where the tensor should be pinned in
-     *
-     * @return Backend tensor
-     */
-    virtual ITensor *set_target(TargetHint target) = 0;
-    /** Returns a pointer to the internal tensor
-     *
-     * @return Tensor
-     */
-    virtual ITensor       *tensor()       = 0;
-    virtual const ITensor *tensor() const = 0;
-    /** Return the target that this tensor is pinned on
-     *
-     * @return Target of the tensor
-     */
-    virtual TargetHint target() const = 0;
-    /** Allocates the tensor */
-    virtual void allocate() = 0;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_ITENSOROBJECT_H__ */
diff --git a/arm_compute/graph/Logger.h b/arm_compute/graph/Logger.h
new file mode 100644
index 0000000..8b87f47
--- /dev/null
+++ b/arm_compute/graph/Logger.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_LOGGER_H__
+#define __ARM_COMPUTE_GRAPH_LOGGER_H__
+
+#include "arm_compute/core/utils/logging/Macros.h"
+
+/** Create a default core logger
+ *
+ * @note It will eventually create all default loggers in don't exist
+ */
+#define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER()                                  \
+    do                                                                             \
+    {                                                                              \
+        if(arm_compute::logging::LoggerRegistry::get().logger("GRAPH") == nullptr) \
+        {                                                                          \
+            arm_compute::logging::LoggerRegistry::get().create_reserved_loggers(); \
+        }                                                                          \
+    } while(false)
+
+#define ARM_COMPUTE_LOG_GRAPH(log_level, x)    \
+    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
+    ARM_COMPUTE_LOG_STREAM("GRAPH", log_level, x)
+
+#define ARM_COMPUTE_LOG_GRAPH_VERBOSE(x)       \
+    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
+    ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::VERBOSE, x)
+
+#define ARM_COMPUTE_LOG_GRAPH_INFO(x)          \
+    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
+    ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::INFO, x)
+
+#define ARM_COMPUTE_LOG_GRAPH_WARNING(x)       \
+    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
+    ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::WARN, x)
+
+#define ARM_COMPUTE_LOG_GRAPH_ERROR(x)         \
+    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
+    ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::ERROR, x)
+
+#endif /* __ARM_COMPUTE_GRAPH_LOGGER_H__ */
diff --git a/arm_compute/graph/NodeContext.h b/arm_compute/graph/NodeContext.h
deleted file mode 100644
index 17ae497..0000000
--- a/arm_compute/graph/NodeContext.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_NODE_CONTEXT_H__
-#define __ARM_COMPUTE_GRAPH_NODE_CONTEXT_H__
-
-#include "arm_compute/core/Error.h"
-#include "arm_compute/graph/NodeParameter.h"
-#include "arm_compute/graph/Types.h"
-#include "support/ToolchainSupport.h"
-
-#include <map>
-#include <memory>
-#include <string>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Node Context class
- *
- * Node context class is used to hold all the parameters required by a node to execute
- */
-class NodeContext
-{
-public:
-    /** Default Constructor
-     *
-     * @param[in] operation Name of the operation
-     */
-    NodeContext(OperationType operation)
-        : _operation(operation), _target(TargetHint::DONT_CARE), _inputs(), _outputs(), _parameters() {};
-    /** Sets the execution target of the node
-     *
-     * @param[in] target Execution target of the node
-     */
-    void set_target(TargetHint target);
-    /** Adds an input tensor to the context
-     *
-     * @param[in] input Input to add
-     */
-    void add_input(arm_compute::ITensor *input);
-    /** Adds an output to the context
-     *
-     * @param[in] output Output to add
-     */
-    void add_output(arm_compute::ITensor *output);
-    /** Adds a parameter to the context
-     *
-     * @param[in] name      Parameter name
-     * @param[in] parameter Parameter to add
-     */
-    template <typename T>
-    void add_parameter(std::string name, T parameter);
-    /** Returns the operation of this node.
-     *
-     * @return The operation type
-     */
-    OperationType operation() const;
-    /** Returns the execution target of this node
-     *
-     * @return The execution target
-     */
-    TargetHint target() const;
-    /** Returns input tensor of a given index
-     *
-     * @param[in] idx Index of the input tensor
-     *
-     * @return A pointer the requested input tensor else nullptr
-     */
-    arm_compute::ITensor *input(size_t idx) const;
-    /** Returns output tensor of a given index
-     *
-     * @param[in] idx Index of the output tensor
-     *
-     * @return A pointer the requested output tensor else nullptr
-     */
-    arm_compute::ITensor *output(size_t idx) const;
-    /** Returns the parameter with the given name
-     *
-     * @param[in] name Parameter name
-     *
-     * @return The requested parameter else an empty object
-     */
-    template <typename T>
-    T parameter(std::string name) const;
-    /** Returns number of inputs
-     *
-     * @return Number of inputs
-     */
-    size_t num_inputs() const;
-    /** Returns number of output
-     *
-     * @return Number of outputs
-     */
-    size_t num_outputs() const;
-
-private:
-    OperationType                       _operation;
-    TargetHint                          _target;
-    std::vector<arm_compute::ITensor *> _inputs;
-    std::vector<arm_compute::ITensor *> _outputs;
-    std::map<std::string, std::unique_ptr<NodeParameterBase>> _parameters;
-};
-
-template <typename T>
-inline void NodeContext::add_parameter(std::string name, T parameter)
-{
-    ARM_COMPUTE_ERROR_ON_MSG(_parameters.find(name) != _parameters.end(), "Parameter already exists!");
-    _parameters[name] = support::cpp14::make_unique<NodeParameter<T>>(name, parameter);
-}
-
-template <typename T>
-inline T NodeContext::parameter(std::string name) const
-{
-    auto it = _parameters.find(name);
-    ARM_COMPUTE_ERROR_ON(it == _parameters.end());
-    return static_cast<NodeParameter<T> *>(it->second.get())->value();
-}
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_NODE_CONTEXT_H__ */
diff --git a/arm_compute/graph/Nodes.h b/arm_compute/graph/Nodes.h
deleted file mode 100644
index 3009a24..0000000
--- a/arm_compute/graph/Nodes.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_NODES_H__
-#define __ARM_COMPUTE_GRAPH_NODES_H__
-
-#include "arm_compute/graph/nodes/ActivationLayer.h"
-#include "arm_compute/graph/nodes/BatchNormalizationLayer.h"
-#include "arm_compute/graph/nodes/BranchLayer.h"
-#include "arm_compute/graph/nodes/ConvolutionLayer.h"
-#include "arm_compute/graph/nodes/DepthConvertLayer.h"
-#include "arm_compute/graph/nodes/DepthwiseConvolutionLayer.h"
-#include "arm_compute/graph/nodes/DequantizationLayer.h"
-#include "arm_compute/graph/nodes/FlattenLayer.h"
-#include "arm_compute/graph/nodes/FloorLayer.h"
-#include "arm_compute/graph/nodes/FullyConnectedLayer.h"
-#include "arm_compute/graph/nodes/L2NormalizeLayer.h"
-#include "arm_compute/graph/nodes/NormalizationLayer.h"
-#include "arm_compute/graph/nodes/PoolingLayer.h"
-#include "arm_compute/graph/nodes/QuantizationLayer.h"
-#include "arm_compute/graph/nodes/ReshapeLayer.h"
-#include "arm_compute/graph/nodes/ResidualLayer.h"
-#include "arm_compute/graph/nodes/SoftmaxLayer.h"
-
-#endif /* __ARM_COMPUTE_GRAPH_NODES_H__ */
diff --git a/arm_compute/graph/OperationRegistry.h b/arm_compute/graph/OperationRegistry.h
deleted file mode 100644
index ae68bf4..0000000
--- a/arm_compute/graph/OperationRegistry.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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_GRAPH_OPERATION_REGISTRY_H__
-#define __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_H__
-
-#include "arm_compute/graph/IOperation.h"
-#include "arm_compute/graph/Types.h"
-#include "support/ToolchainSupport.h"
-
-#include <map>
-#include <memory>
-#include <string>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Registry holding all the supported operations */
-class OperationRegistry
-{
-public:
-    /** Gets operation registry instance
-     *
-     * @return Operation registry instance
-     */
-    static OperationRegistry &get();
-    /** Finds an operation in the registry
-     *
-     * @param[in] operation Type of the operation to find
-     * @param[in] target    Target of the operation
-     *
-     * @return Pointer to the operation functor if found, else nullptr
-     */
-    IOperation *find_operation(OperationType operation, TargetHint target);
-    /** Checks if an operation for a given target exists
-     *
-     * @param[in] operation Operation type
-     * @param[in] target    Execution target
-     *
-     * @return True if exists else false
-     */
-    bool contains(OperationType operation, TargetHint target) const;
-    /** Registers an operation to the registry
-     *
-     * @param operation Operation to register
-     */
-    template <typename T>
-    void add_operation(OperationType operation);
-
-private:
-    /** Default Constructor */
-    OperationRegistry();
-
-private:
-    std::map<OperationType, std::vector<std::unique_ptr<IOperation>>> _registered_ops;
-};
-
-template <typename T>
-inline void OperationRegistry::add_operation(OperationType operation)
-{
-    _registered_ops[operation].emplace_back(support::cpp14::make_unique<T>());
-}
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_H__ */
diff --git a/arm_compute/graph/PassManager.h b/arm_compute/graph/PassManager.h
new file mode 100644
index 0000000..9f32a45
--- /dev/null
+++ b/arm_compute/graph/PassManager.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_PASSMANAGER_H__
+#define __ARM_COMPUTE_GRAPH_PASSMANAGER_H__
+
+#include "arm_compute/graph/IGraphMutator.h"
+
+#include <memory>
+#include <vector>
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class Graph;
+
+/** Pass manager
+ *
+ * Responsible for performing the mutating graph passes with a given order
+ **/
+class PassManager final
+{
+public:
+    /** Constructor */
+    PassManager();
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    PassManager(const PassManager &) = delete;
+    /** Default move constructor */
+    PassManager(PassManager &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    PassManager &operator=(const PassManager &) = delete;
+    /** Default move assignment operator */
+    PassManager &operator=(PassManager &&) = default;
+    /** Mutation passes accessors
+     *
+     * @return Returns the vector with the mutation passes that are to be executed on a graph
+     */
+    const std::vector<std::unique_ptr<IGraphMutator>> &passes() const;
+    /** Accessor of a pass at a given index
+     *
+     * @param[in] index Index of the requested pass
+     *
+     * @return A pointer to the given pass if exists else nullptr
+     */
+    IGraphMutator *pass(size_t index);
+    /** Appends a mutation pass
+     *
+     * @param[in] pass Pass to append
+     */
+    void append(std::unique_ptr<IGraphMutator> pass);
+    /** Clears all the passes */
+    void clear();
+    /** Runs all the mutation passes on a given graph
+     *
+     * @param[in] g Graph to run the mutations on
+     */
+    void run_all(Graph &g);
+    /** Runs a specific mutation pass on a given graph
+     *
+     * @param[in] g     Graph to run the mutation on
+     * @param[in] index Index of the mutation to execute
+     */
+    void run(Graph &g, size_t index);
+
+private:
+    std::vector<std::unique_ptr<IGraphMutator>> _passes; /**< Vector of graph passes */
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_PASSMANAGER_H__ */
diff --git a/arm_compute/graph/SubGraph.h b/arm_compute/graph/SubGraph.h
deleted file mode 100644
index e3217e7..0000000
--- a/arm_compute/graph/SubGraph.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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_GRAPH_SUBGRAPH_H__
-#define __ARM_COMPUTE_GRAPH_SUBGRAPH_H__
-
-#include "arm_compute/graph/Graph.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/SubTensor.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
-
-#include <memory>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** SubGraph class */
-class SubGraph
-{
-public:
-    /** Constructor */
-    SubGraph();
-    /** Adds a node to the graph
-     *
-     * @param[in] node Node to add
-     */
-    void add_node(std::unique_ptr<INode> node);
-    /** Adds a tensor to the graph
-     *
-     * @param[in] tensor Tensor to add
-     */
-    void add_tensor_object(std::unique_ptr<ITensorObject> tensor);
-    /** Constructs a graph from a subgraph
-     *
-     * @param[in] ctx    Parent graph context
-     * @param[in] input  Input to the graph
-     * @param[in] output Output to the graph
-     *
-     * @return A graph
-     */
-    std::unique_ptr<Graph> construct(const GraphContext &ctx, std::unique_ptr<ITensorObject> input, std::unique_ptr<ITensorObject> output);
-    /** Checks if the subgraph has an input
-     *
-     * @return True if the sub-graph has an input else false
-     */
-    bool has_input() const;
-    /** Checks if the subgraph has an output
-     *
-     * @return True if the sub-graph has an output else false
-     */
-    bool has_output() const;
-
-private:
-    std::vector<std::unique_ptr<INode>> _nodes;
-    std::unique_ptr<ITensorObject>      _input;
-    std::unique_ptr<ITensorObject>      _output;
-};
-
-SubGraph &operator<<(SubGraph &graph, Tensor &&tensor);
-SubGraph &operator<<(SubGraph &graph, SubTensor &&sub_tensor);
-
-template <typename Node>
-SubGraph &operator<<(SubGraph &sub_graph, Node node)
-{
-    sub_graph.add_node(arm_compute::support::cpp14::make_unique<Node>(std::move(node)));
-    return sub_graph;
-}
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_INODE_H__ */
diff --git a/arm_compute/graph/SubTensor.h b/arm_compute/graph/SubTensor.h
deleted file mode 100644
index 43b835d..0000000
--- a/arm_compute/graph/SubTensor.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_SUBTENSOR_H__
-#define __ARM_COMPUTE_GRAPH_SUBTENSOR_H__
-
-#include "arm_compute/graph/ITensorAccessor.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-#include "support/ToolchainSupport.h"
-
-#include <memory>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** SubTensor class */
-class SubTensor final : public ITensorObject
-{
-public:
-    /** Default Constructor */
-    SubTensor();
-    /** Constructor
-     *
-     * @param[in] parent        Parent to create sub-tensor from
-     * @param[in] tensor_shape  Sub-tensor shape
-     * @param[in] coords        Starting coordinates of the sub-tensor in the parent tensor
-     * @param[in] extend_parent (Optional) Extend parent with subtensor shape if subtensor indexes out of bounds
-     */
-    SubTensor(Tensor &parent, TensorShape tensor_shape, Coordinates coords, bool extend_parent = false);
-    /** Constructor
-     *
-     * @param[in] parent        Parent to create sub-tensor from
-     * @param[in] tensor_shape  Sub-tensor shape
-     * @param[in] coords        Starting coordinates of the sub-tensor in the parent tensor
-     * @param[in] target        Execution target
-     * @param[in] extend_parent (Optional) Extend parent with subtensor shape if subtensor indexes out of bounds
-     */
-    SubTensor(arm_compute::ITensor *parent, TensorShape tensor_shape, Coordinates coords, TargetHint target, bool extend_parent = false);
-    /** Prevent instances of this class from being copied (As this class contains pointers) */
-    SubTensor(const SubTensor &) = delete;
-    /** Prevent instances of this class from being copied (As this class contains pointers) */
-    SubTensor &operator=(const SubTensor &) = delete;
-    /** Allow instances of this class to be moved */
-    SubTensor(SubTensor &&) = default;
-    /** Allow instances of this class to be moved */
-    SubTensor &operator=(SubTensor &&) = default;
-    /** Default Destructor */
-    ~SubTensor() = default;
-
-    // Inherited methods overriden:
-    bool                  call_accessor() override;
-    bool                  has_accessor() const override;
-    arm_compute::ITensor *set_target(TargetHint target) override;
-    arm_compute::ITensor       *tensor() override;
-    const arm_compute::ITensor *tensor() const override;
-    TargetHint                  target() const override;
-    void                        allocate() override;
-
-private:
-    /** Instantiates a sub-tensor */
-    void instantiate_subtensor();
-
-private:
-    TargetHint                            _target;        /**< Target that this tensor is pinned on */
-    TensorShape                           _tensor_shape;  /**< SubTensor shape */
-    Coordinates                           _coords;        /**< SubTensor Coordinates */
-    arm_compute::ITensor                 *_parent;        /**< Parent tensor */
-    std::unique_ptr<arm_compute::ITensor> _subtensor;     /**< SubTensor */
-    bool                                  _extend_parent; /**< Parent extension flag */
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SUBTENSOR_H__ */
diff --git a/arm_compute/graph/Tensor.h b/arm_compute/graph/Tensor.h
index e5821dc..5199ac2 100644
--- a/arm_compute/graph/Tensor.h
+++ b/arm_compute/graph/Tensor.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -24,99 +24,91 @@
 #ifndef __ARM_COMPUTE_GRAPH_TENSOR_H__
 #define __ARM_COMPUTE_GRAPH_TENSOR_H__
 
-#include "arm_compute/graph/ITensorAccessor.h"
-#include "arm_compute/graph/ITensorObject.h"
 #include "arm_compute/graph/Types.h"
-#include "support/ToolchainSupport.h"
+
+#include "arm_compute/graph/ITensorAccessor.h"
+#include "arm_compute/graph/ITensorHandle.h"
+#include "arm_compute/graph/TensorDescriptor.h"
 
 #include <memory>
+#include <set>
 
 namespace arm_compute
 {
 namespace graph
 {
-/** Tensor class */
-class Tensor final : public ITensorObject
+/** Tensor object **/
+class Tensor final
 {
 public:
-    /** Constructor
+    /** Default constructor
      *
-     * @param[in] info Tensor info to use
+     * @param[in] id   Tensor ID
+     * @param[in] desc Tensor information
      */
-    Tensor(TensorInfo &&info);
-    /** Constructor
+    Tensor(TensorID id, TensorDescriptor desc);
+    /** Tensor ID accessor
      *
-     * @param[in] accessor Tensor accessor
+     * @return Tensor ID
      */
-    template <typename AccessorType>
-    Tensor(std::unique_ptr<AccessorType> accessor)
-        : _target(TargetHint::DONT_CARE), _info(), _accessor(std::move(accessor)), _tensor(nullptr)
-    {
-    }
-    /** Constructor
+    TensorID id() const;
+    /** TensorInfo metadata accessor
      *
-     * @param[in] accessor Tensor accessor
+     * @return Tensor descriptor metadata
      */
-    template <typename AccessorType>
-    Tensor(AccessorType &&accessor)
-        : _target(TargetHint::DONT_CARE), _info(), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr)
-    {
-    }
-    /** Constructor
+    TensorDescriptor &desc();
+    /** TensorInfo metadata accessor
      *
-     * @param[in] info     Tensor info to use
-     * @param[in] accessor Tensor accessor
+     * @return Tensor descriptor metadata
      */
-    template <typename AccessorType>
-    Tensor(TensorInfo &&info, std::unique_ptr<AccessorType> &&accessor)
-        : _target(TargetHint::DONT_CARE), _info(info), _accessor(std::move(accessor)), _tensor(nullptr)
-    {
-    }
-    /** Constructor
+    const TensorDescriptor &desc() const;
+    /** Sets the backend tensor
      *
-     * @param[in] info     Tensor info to use
-     * @param[in] accessor Tensor accessor
+     * @param[in] backend_tensor Backend tensor to set
      */
-    template <typename AccessorType>
-    Tensor(TensorInfo &&info, AccessorType &&accessor)
-        : _target(TargetHint::DONT_CARE), _info(info), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr)
-    {
-    }
-    /** Default Destructor */
-    ~Tensor() = default;
-    /** Move Constructor
+    void set_handle(std::unique_ptr<ITensorHandle> backend_tensor);
+    /** Backend tensor handle accessor
      *
-     * @param[in] src Tensor to move
+     * @return Backend tensor handle
      */
-    Tensor(Tensor &&src) noexcept;
-
-    /** Sets the given TensorInfo to the tensor
+    ITensorHandle *handle();
+    /** Sets the backend tensor accessor
      *
-     * @param[in] info TensorInfo to set
+     * @param[in] accessor Accessor to set
      */
-    void set_info(TensorInfo &&info);
-    /** Returns tensor's TensorInfo
+    void set_accessor(std::unique_ptr<ITensorAccessor> accessor);
+    /** Backend tensor accessor
      *
-     * @return TensorInfo of the tensor
+     * @return Backend tensor accessor
      */
-    const TensorInfo &info() const;
-    /** Allocates and fills the tensor if needed */
-    void allocate_and_fill_if_needed();
-
-    // Inherited methods overriden:
-    bool                  call_accessor() override;
-    bool                  has_accessor() const override;
-    arm_compute::ITensor *set_target(TargetHint target) override;
-    arm_compute::ITensor       *tensor() override;
-    const arm_compute::ITensor *tensor() const override;
-    TargetHint                  target() const override;
-    void                        allocate() override;
+    ITensorAccessor *accessor();
+    /** Calls accessor on tensor
+     *
+     * @return True if the accessor was called else false
+     */
+    bool call_accessor();
+    /** Binds the tensor with an edge
+     *
+     * @param[in] eid Edge ID that is bound to the tensor
+     */
+    void bind_edge(EdgeID eid);
+    /** Unbinds an edge from a tensor
+     *
+     * @param[in] eid Edge to unbind
+     */
+    void unbind_edge(EdgeID eid);
+    /** Accessor the edges that are bound with the tensor
+     *
+     * @return Bound edges
+     */
+    const std::set<EdgeID> bound_edges() const;
 
 private:
-    TargetHint                            _target;   /**< Target that this tensor is pinned on */
-    TensorInfo                            _info;     /**< Tensor metadata */
-    std::unique_ptr<ITensorAccessor>      _accessor; /**< Tensor Accessor */
-    std::unique_ptr<arm_compute::ITensor> _tensor;   /**< Tensor */
+    TensorID                         _id;          /**< Tensor id */
+    TensorDescriptor                 _desc;        /**< Tensor metadata */
+    std::unique_ptr<ITensorHandle>   _handle;      /**< Tensor Handle */
+    std::unique_ptr<ITensorAccessor> _accessor;    /**< Tensor Accessor */
+    std::set<EdgeID>                 _bound_edges; /**< Edges bound to this tensor */
 };
 } // namespace graph
 } // namespace arm_compute
diff --git a/arm_compute/graph/TensorDescriptor.h b/arm_compute/graph/TensorDescriptor.h
new file mode 100644
index 0000000..704f015
--- /dev/null
+++ b/arm_compute/graph/TensorDescriptor.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_TENSOR_DESCRIPTOR_H__
+#define __ARM_COMPUTE_GRAPH_TENSOR_DESCRIPTOR_H__
+
+#include "arm_compute/graph/Types.h"
+
+#include "arm_compute/core/utils/misc/ICloneable.h"
+
+#include <memory>
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Tensor metadata class */
+struct TensorDescriptor final : public misc::ICloneable<TensorDescriptor>
+{
+    /** Default Constructor **/
+    TensorDescriptor() = default;
+    /** Constructor
+     *
+     * @param[in] tensor_shape       Tensor shape
+     * @param[in] tensor_data_type   Tensor data type
+     * @param[in] tensor_quant_info  Tensor quantization info
+     * @param[in] tensor_data_layout Tensor data layout
+     * @param[in] tensor_target      Target to allocate the tensor for
+     */
+    TensorDescriptor(TensorShape      tensor_shape,
+                     DataType         tensor_data_type,
+                     QuantizationInfo tensor_quant_info  = QuantizationInfo(),
+                     DataLayout       tensor_data_layout = DataLayout::NCHW,
+                     Target           tensor_target      = Target::UNSPECIFIED)
+        : shape(tensor_shape), data_type(tensor_data_type), layout(tensor_data_layout), quant_info(tensor_quant_info), target(tensor_target)
+    {
+    }
+    /** Sets tensor descriptor shape
+     *
+     * @param[in] tensor_shape Tensor shape to set
+     *
+     * @return This tensor descriptor
+     */
+    TensorDescriptor &set_shape(TensorShape &tensor_shape)
+    {
+        shape = tensor_shape;
+        return *this;
+    }
+    /** Sets tensor descriptor data type
+     *
+     * @param[in] tensor_data_type Data type
+     *
+     * @return This tensor descriptor
+     */
+    TensorDescriptor &set_data_type(DataType tensor_data_type)
+    {
+        data_type = tensor_data_type;
+        return *this;
+    }
+    /** Sets tensor descriptor data layout
+     *
+     * @param[in] data_layout Data layout
+     *
+     * @return This tensor descriptor
+     */
+    TensorDescriptor &set_layout(DataLayout data_layout)
+    {
+        layout = data_layout;
+        return *this;
+    }
+    /** Sets tensor descriptor quantization info
+     *
+     * @param[in] tensor_quant_info Quantization information
+     *
+     * @return This tensor descriptor
+     */
+    TensorDescriptor &set_quantization_info(QuantizationInfo tensor_quant_info)
+    {
+        quant_info = tensor_quant_info;
+        return *this;
+    }
+
+    // Inherited methods overridden:
+    std::unique_ptr<TensorDescriptor> clone() const override
+    {
+        return support::cpp14::make_unique<TensorDescriptor>(*this);
+    }
+
+    TensorShape      shape{};                        /**< Tensor shape */
+    DataType         data_type{ DataType::UNKNOWN }; /**< Data type */
+    DataLayout       layout{ DataLayout::NCHW };     /**< Data layout */
+    QuantizationInfo quant_info{};                   /**< Quantization info */
+    Target           target{ Target::UNSPECIFIED };  /**< Target */
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_TENSOR_DESCRIPTOR_H__ */
diff --git a/arm_compute/graph/TypePrinter.h b/arm_compute/graph/TypePrinter.h
new file mode 100644
index 0000000..6babd39
--- /dev/null
+++ b/arm_compute/graph/TypePrinter.h
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_TYPE_PRINTER_H__
+#define __ARM_COMPUTE_GRAPH_TYPE_PRINTER_H__
+
+#include "arm_compute/core/Error.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Formatted output of the Dimensions type. */
+template <typename T>
+inline ::std::ostream &operator<<(::std::ostream &os, const arm_compute::Dimensions<T> &dimensions)
+{
+    if(dimensions.num_dimensions() > 0)
+    {
+        os << dimensions[0];
+
+        for(unsigned int d = 1; d < dimensions.num_dimensions(); ++d)
+        {
+            os << "x" << dimensions[d];
+        }
+    }
+
+    return os;
+}
+
+/** Formatted output of the Size2D type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const Size2D &size)
+{
+    os << size.width << "x" << size.height;
+
+    return os;
+}
+
+/** Formatted output of the DataType type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const DataType &data_type)
+{
+    switch(data_type)
+    {
+        case DataType::UNKNOWN:
+            os << "UNKNOWN";
+            break;
+        case DataType::U8:
+            os << "U8";
+            break;
+        case DataType::QS8:
+            os << "QS8";
+            break;
+        case DataType::QASYMM8:
+            os << "QASYMM8";
+            break;
+        case DataType::S8:
+            os << "S8";
+            break;
+        case DataType::U16:
+            os << "U16";
+            break;
+        case DataType::S16:
+            os << "S16";
+            break;
+        case DataType::QS16:
+            os << "QS16";
+            break;
+        case DataType::U32:
+            os << "U32";
+            break;
+        case DataType::S32:
+            os << "S32";
+            break;
+        case DataType::U64:
+            os << "U64";
+            break;
+        case DataType::S64:
+            os << "S64";
+            break;
+        case DataType::F16:
+            os << "F16";
+            break;
+        case DataType::F32:
+            os << "F32";
+            break;
+        case DataType::F64:
+            os << "F64";
+            break;
+        case DataType::SIZET:
+            os << "SIZET";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the Target. */
+inline ::std::ostream &operator<<(::std::ostream &os, const Target &target)
+{
+    switch(target)
+    {
+        case Target::UNSPECIFIED:
+            os << "UNSPECIFIED";
+            break;
+        case Target::NEON:
+            os << "NEON";
+            break;
+        case Target::CL:
+            os << "CL";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the DataLayout */
+inline ::std::ostream &operator<<(::std::ostream &os, const DataLayout &data_layout)
+{
+    switch(data_layout)
+    {
+        case DataLayout::NCHW:
+            os << "NCHW";
+            break;
+        case DataLayout::NHWC:
+            os << "NHWC";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the activation function type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const ActivationLayerInfo::ActivationFunction &act_function)
+{
+    switch(act_function)
+    {
+        case ActivationLayerInfo::ActivationFunction::ABS:
+            os << "ABS";
+            break;
+        case ActivationLayerInfo::ActivationFunction::LINEAR:
+            os << "LINEAR";
+            break;
+        case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+            os << "LOGISTIC";
+            break;
+        case ActivationLayerInfo::ActivationFunction::RELU:
+            os << "RELU";
+            break;
+        case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
+            os << "BOUNDED_RELU";
+            break;
+        case ActivationLayerInfo::ActivationFunction::LEAKY_RELU:
+            os << "LEAKY_RELU";
+            break;
+        case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+            os << "SOFT_RELU";
+            break;
+        case ActivationLayerInfo::ActivationFunction::SQRT:
+            os << "SQRT";
+            break;
+        case ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU:
+            os << "LU_BOUNDED_RELU";
+            break;
+        case ActivationLayerInfo::ActivationFunction::SQUARE:
+            os << "SQUARE";
+            break;
+        case ActivationLayerInfo::ActivationFunction::TANH:
+            os << "TANH";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+inline std::string to_string(const ActivationLayerInfo::ActivationFunction &act_function)
+{
+    std::stringstream str;
+    str << act_function;
+    return str.str();
+}
+
+/** Formatted output of the PoolingType type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const PoolingType &pool_type)
+{
+    switch(pool_type)
+    {
+        case PoolingType::AVG:
+            os << "AVG";
+            break;
+        case PoolingType::MAX:
+            os << "MAX";
+            break;
+        case PoolingType::L2:
+            os << "L2";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the NormType type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const NormType &norm_type)
+{
+    switch(norm_type)
+    {
+        case NormType::CROSS_MAP:
+            os << "CROSS_MAP";
+            break;
+        case NormType::IN_MAP_1D:
+            os << "IN_MAP_1D";
+            break;
+        case NormType::IN_MAP_2D:
+            os << "IN_MAP_2D";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the EltwiseOperation type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const EltwiseOperation &eltwise_op)
+{
+    switch(eltwise_op)
+    {
+        case EltwiseOperation::ADD:
+            os << "ADD";
+            break;
+        case EltwiseOperation::MUL:
+            os << "MUL";
+            break;
+        case EltwiseOperation::SUB:
+            os << "SUB";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the ConvolutionMethod type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethod &method)
+{
+    switch(method)
+    {
+        case ConvolutionMethod::DEFAULT:
+            os << "DEFAULT";
+            break;
+        case ConvolutionMethod::DIRECT:
+            os << "DIRECT";
+            break;
+        case ConvolutionMethod::GEMM:
+            os << "GEMM";
+            break;
+        case ConvolutionMethod::WINOGRAD:
+            os << "WINOGRAD";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the FastMathHint type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const FastMathHint &hint)
+{
+    switch(hint)
+    {
+        case FastMathHint::ENABLED:
+            os << "ENABLED";
+            break;
+        case FastMathHint::DISABLED:
+            os << "DISABLED";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the DepthwiseConvolutionMethod type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const DepthwiseConvolutionMethod &method)
+{
+    switch(method)
+    {
+        case DepthwiseConvolutionMethod::DEFAULT:
+            os << "DEFAULT";
+            break;
+        case DepthwiseConvolutionMethod::GEMV:
+            os << "GEMV";
+            break;
+        case DepthwiseConvolutionMethod::OPTIMIZED_3x3:
+            os << "OPTIMIZED_3x3";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+    }
+
+    return os;
+}
+
+/** Formatted output of the PadStrideInfo type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const PadStrideInfo &pad_stride_info)
+{
+    os << pad_stride_info.stride().first << "," << pad_stride_info.stride().second;
+    os << ";";
+    os << pad_stride_info.pad_left() << "," << pad_stride_info.pad_right() << ","
+       << pad_stride_info.pad_top() << "," << pad_stride_info.pad_bottom();
+
+    return os;
+}
+
+/** Formatted output of the QuantizationInfo type. */
+inline ::std::ostream &operator<<(::std::ostream &os, const QuantizationInfo &quantization_info)
+{
+    os << "Scale:" << quantization_info.scale << "~"
+       << "Offset:" << quantization_info.offset;
+    return os;
+}
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_TYPE_PRINTER_H__ */
diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h
index a5d6ae8..c19bb1a 100644
--- a/arm_compute/graph/Types.h
+++ b/arm_compute/graph/Types.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -24,95 +24,149 @@
 #ifndef __ARM_COMPUTE_GRAPH_TYPES_H__
 #define __ARM_COMPUTE_GRAPH_TYPES_H__
 
-#include "arm_compute/core/ITensor.h"
-#include "arm_compute/core/SubTensorInfo.h"
-#include "arm_compute/core/TensorInfo.h"
-#include "arm_compute/core/utils/logging/Macros.h"
+#include "arm_compute/core/Error.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/core/utils/strong_type/StrongType.h"
+#include "arm_compute/core/utils/strong_type/StrongTypeAttributes.h"
 
-/** Create a default core logger
- *
- * @note It will eventually create all default loggers in don't exist
- */
-#define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER()                                  \
-    do                                                                             \
-    {                                                                              \
-        if(arm_compute::logging::LoggerRegistry::get().logger("GRAPH") == nullptr) \
-        {                                                                          \
-            arm_compute::logging::LoggerRegistry::get().create_reserved_loggers(); \
-        }                                                                          \
-    } while(false)
-
-#define ARM_COMPUTE_LOG_GRAPH(log_level, x)    \
-    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
-    ARM_COMPUTE_LOG_STREAM("GRAPH", log_level, x)
-
-#define ARM_COMPUTE_LOG_GRAPH_INFO(x)          \
-    ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \
-    ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::INFO, x)
+#include <limits>
+#include <string>
 
 namespace arm_compute
 {
 namespace graph
 {
-using arm_compute::ActivationLayerInfo;
+using arm_compute::Status;
+
 using arm_compute::Coordinates;
 using arm_compute::DataType;
-using arm_compute::DimensionRoundingType;
-using arm_compute::ITensorInfo;
+using arm_compute::DataLayout;
+using arm_compute::DataLayoutDimension;
+using arm_compute::TensorShape;
+using arm_compute::Size2D;
+
+using arm_compute::ActivationLayerInfo;
 using arm_compute::NormType;
 using arm_compute::NormalizationLayerInfo;
 using arm_compute::PadStrideInfo;
 using arm_compute::PoolingLayerInfo;
 using arm_compute::PoolingType;
-using arm_compute::SubTensorInfo;
-using arm_compute::TensorInfo;
-using arm_compute::TensorShape;
-using arm_compute::WeightsInfo;
+using arm_compute::DimensionRoundingType;
 
-using arm_compute::logging::LogLevel;
-using arm_compute::ConvertPolicy;
+using TensorID   = unsigned int;
+using NodeID     = unsigned int;
+using EdgeID     = unsigned int;
+using Activation = arm_compute::ActivationLayerInfo::ActivationFunction;
 
-/**< Execution hint to the graph executor */
-enum class TargetHint
+/**< GraphID strong type */
+using GraphID = strong_type::StrongType<unsigned int, struct graph_id_t, strong_type::Comparable>;
+
+/**< Constant TensorID specifying an equivalent of null tensor */
+constexpr TensorID NullTensorID = std::numeric_limits<TensorID>::max();
+/**< Constant NodeID specifying an equivalent of null node */
+constexpr NodeID EmptyNodeID = std::numeric_limits<NodeID>::max();
+/**< Constant EdgeID specifying an equivalent of null edge */
+constexpr EdgeID EmptyEdgeID = std::numeric_limits<EdgeID>::max();
+
+// Forward declarations
+class TensorDescriptor;
+
+/** Graph configuration structure */
+struct GraphConfig
 {
-    DONT_CARE, /**< Run node in any device */
-    OPENCL,    /**< Run node on an OpenCL capable device (GPU) */
-    NEON       /**< Run node on a NEON capable device */
+    bool use_function_memory_manager{ true };   /**< Use a memory manager to manage per-funcion auxilary memory */
+    bool use_transition_memory_manager{ true }; /**< Use a memory manager to manager transition buffer memory */
+    bool use_tuner{ false };                    /**< Use a tuner in tunable backends */
+    int  num_threads{ -1 };                     /**< Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is. */
 };
 
-/** Convolution method hint to the graph executor */
-enum class ConvolutionMethodHint
+/**< Device target types */
+enum class Target
 {
-    GEMM,  /**< Convolution using GEMM */
-    DIRECT /**< Direct convolution */
+    UNSPECIFIED, /**< Unspecified Target */
+    NEON,        /**< NEON capable target device */
+    CL,          /**< OpenCL capable target device */
+    GC,          /**< GLES compute capable target device */
 };
 
-/** Supported layer operations */
-enum class OperationType
+/** Supported Element-wise operations */
+enum class EltwiseOperation
+{
+    ADD, /**< Arithmetic addition */
+    SUB, /**< Arithmetic subtraction */
+    MUL  /**< Arithmetic multiplication */
+};
+
+/** Supported Convolution layer methods */
+enum class ConvolutionMethod
+{
+    DEFAULT, /**< Default approach using internal heuristics */
+    GEMM,    /**< GEMM based convolution */
+    DIRECT,  /**< Deep direct convolution */
+    WINOGRAD /**< Winograd based convolution */
+};
+
+/** Supported Depthwise Convolution layer methods */
+enum class DepthwiseConvolutionMethod
+{
+    DEFAULT,       /**< Default approach using internal heuristics */
+    GEMV,          /**< Generic GEMV based depthwise convolution */
+    OPTIMIZED_3x3, /**< Optimized 3x3 direct depthwise convolution */
+};
+
+/** Enable or disable fast math for Convolution layer */
+enum class FastMathHint
+{
+    ENABLED,  /**< Fast math enabled for Convolution layer */
+    DISABLED, /**< Fast math disabled for Convolution layer */
+};
+
+/** Supported nodes */
+enum class NodeType
 {
     ActivationLayer,
-    ArithmeticAddition,
     BatchNormalizationLayer,
     ConvolutionLayer,
-    DepthConvertLayer,
+    DepthConcatenateLayer,
     DepthwiseConvolutionLayer,
-    DequantizationLayer,
+    EltwiseLayer,
     FlattenLayer,
-    FloorLayer,
     FullyConnectedLayer,
-    L2NormalizeLayer,
     NormalizationLayer,
     PoolingLayer,
-    QuantizationLayer,
     ReshapeLayer,
-    SoftmaxLayer
+    ScaleLayer,
+    SoftmaxLayer,
+    SplitLayer,
+
+    Input,
+    Output,
+    Const,
 };
 
-/** Branch layer merging method */
-enum class BranchMergeMethod
+/** Backend Memory Manager affinity **/
+enum class MemoryManagerAffinity
 {
-    DEPTH_CONCATENATE /**< Concatenate across depth */
+    Buffer, /**< Affinity at buffer level */
+    Offset  /**< Affinity at offset level */
+};
+
+/** NodeID-index struct
+ *
+ * Used to describe connections
+ */
+struct NodeIdxPair
+{
+    NodeID node_id; /**< Node ID */
+    size_t index;   /**< Index */
+};
+
+/** Common node parameters */
+struct NodeParams
+{
+    std::string name;   /**< Node name */
+    Target      target; /**< Node target */
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /*__ARM_COMPUTE_GRAPH_TYPES_H__*/
+#endif /* __ARM_COMPUTE_GRAPH_TYPES_H__ */
diff --git a/arm_compute/graph/Utils.h b/arm_compute/graph/Utils.h
new file mode 100644
index 0000000..582d47e
--- /dev/null
+++ b/arm_compute/graph/Utils.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_UTILS_H__
+#define __ARM_COMPUTE_GRAPH_UTILS_H__
+
+#include "arm_compute/graph/Graph.h"
+#include "arm_compute/graph/PassManager.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward Declaration
+class GraphContext;
+
+/** Returns the tensor descriptor of a given tensor
+ *
+ * @param[in] g   Graph that the tensor belongs to
+ * @param[in] tid Tensor ID
+ *
+ * @return Tensor descriptor if tensor was found else empty descriptor
+ */
+inline TensorDescriptor get_tensor_descriptor(const Graph &g, TensorID tid)
+{
+    const Tensor *tensor = g.tensor(tid);
+    return (tensor != nullptr) ? tensor->desc() : TensorDescriptor();
+}
+/** Sets an accessor on a given tensor
+ *
+ * @param[in] tensor   Tensor to set the accessor to
+ * @param[in] accessor Accessor to set
+ *
+ * @return True if accessor was set else false
+ */
+inline Status set_tensor_accessor(Tensor *tensor, std::unique_ptr<ITensorAccessor> accessor)
+{
+    ARM_COMPUTE_RETURN_ERROR_ON(tensor == nullptr);
+    tensor->set_accessor(std::move(accessor));
+
+    return Status{};
+}
+/** Checks if a specific target is supported
+ *
+ * @param[in] target Target to check
+ *
+ * @return True if target is support else false
+ */
+bool is_target_supported(Target target);
+/** Returns default target for execution
+ *
+ * @note If an OpenCL backend exists then OpenCL is returned,
+ *       else if the NEON backend exists returns NEON as target.
+ *       If no backends are registered an error is raised.
+ *
+ * @return Default target
+ */
+Target get_default_target();
+/** Forces a single target to all graph constructs
+ *
+ * @param[in] g      Graph to force target on
+ * @param[in] target Target to force
+ */
+void force_target_to_graph(Graph &g, Target target);
+/** Creates a default @ref PassManager
+ *
+ * @param[in] target Target to create the pass manager for
+ *
+ * @return A PassManager with default mutating passes
+ */
+PassManager create_default_pass_manager(Target target);
+/** Default setups the graph context if not done manually
+ *
+ * @param[in] ctx Graph Context
+ */
+void setup_default_graph_context(GraphContext &ctx);
+/** Get size of a tensor's given dimension depending on its layout
+ *
+ * @param[in] descriptor            Descriptor
+ * @param[in] data_layout_dimension Tensor data layout dimension
+ *
+ * @return Size of requested dimension
+ */
+size_t get_dimension_size(const TensorDescriptor &descriptor, const DataLayoutDimension data_layout_dimension);
+/** Get index of a tensor's given dimension depending on its layout
+ *
+ * @param[in] descriptor            Descriptor
+ * @param[in] data_layout_dimension Tensor data layout dimension
+ *
+ * @return Idx of given dimension
+ */
+size_t get_dimension_idx(const TensorDescriptor &descriptor, const DataLayoutDimension data_layout_dimension);
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_UTILS_H__ */
diff --git a/arm_compute/graph/Workload.h b/arm_compute/graph/Workload.h
new file mode 100644
index 0000000..8c7e79e
--- /dev/null
+++ b/arm_compute/graph/Workload.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_WORKLOAD_H__
+#define __ARM_COMPUTE_GRAPH_WORKLOAD_H__
+
+#include "arm_compute/graph/GraphContext.h"
+#include "arm_compute/runtime/IFunction.h"
+#include "arm_compute/runtime/IMemoryGroup.h"
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class ITensorHandle;
+class INode;
+class Tensor;
+class Graph;
+
+struct ExecutionTask;
+
+void execute_task(ExecutionTask &task);
+
+/** Task executor */
+class TaskExecutor final
+{
+private:
+    /** Default constructor **/
+    TaskExecutor();
+
+public:
+    /** Task executor accessor
+     *
+     * @return Task executor instance
+     */
+    static TaskExecutor &get();
+    /** Function that is responsible for executing tasks */
+    std::function<decltype(execute_task)> execute_function;
+};
+
+/** Execution task
+ *
+ * Contains all the information required to execute a given task
+ */
+struct ExecutionTask
+{
+    std::unique_ptr<arm_compute::IFunction> task = {}; /**< Task to execute */
+    INode                                  *node = {}; /**< Node bound to this workload */
+
+    /** Function operator */
+    void operator()();
+
+    /** Prepare execution task */
+    void prepare();
+};
+
+/** Execution workload */
+struct ExecutionWorkload
+{
+    std::vector<Tensor *>      inputs  = {};          /**< Input handles */
+    std::vector<Tensor *>      outputs = {};          /**< Output handles */
+    std::vector<ExecutionTask> tasks   = {};          /**< Execution workload */
+    Graph                     *graph   = { nullptr }; /**< Graph bound to the workload */
+    GraphContext              *ctx     = { nullptr }; /**< Graph execution context */
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_WORKLOAD_H__ */
diff --git a/arm_compute/graph/nodes/FloorLayer.h b/arm_compute/graph/algorithms/Algorithms.h
similarity index 62%
copy from arm_compute/graph/nodes/FloorLayer.h
copy to arm_compute/graph/algorithms/Algorithms.h
index 146e2c1..f89856f 100644
--- a/arm_compute/graph/nodes/FloorLayer.h
+++ b/arm_compute/graph/algorithms/Algorithms.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,25 +21,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_ALGORITHMS_H__
+#define __ARM_COMPUTE_GRAPH_ALGORITHMS_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-namespace arm_compute
-{
-namespace graph
-{
-/** Floor layer node */
-class FloorLayer final : public INode
-{
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
+#include "arm_compute/graph/algorithms/BFS.h"
 
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_ALGORITHMS_H__ */
diff --git a/arm_compute/graph/algorithms/BFS.h b/arm_compute/graph/algorithms/BFS.h
new file mode 100644
index 0000000..36ca872
--- /dev/null
+++ b/arm_compute/graph/algorithms/BFS.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_ALGORITHM_BFS_H__
+#define __ARM_COMPUTE_GRAPH_ALGORITHM_BFS_H__
+
+#include "arm_compute/graph/Graph.h"
+
+#include <list>
+#include <vector>
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace detail
+{
+/** Checks if all the input dependencies of a node have been visited
+ *
+ * @param[in] node    Node to check
+ * @param[in] visited Vector that contains the visited information
+ *
+ * @return True if all inputs dependencies have been visited else false
+ */
+inline bool all_inputs_are_visited(const INode *node, const std::vector<bool> &visited)
+{
+    ARM_COMPUTE_ERROR_ON(node == nullptr);
+    const Graph *graph = node->graph();
+    ARM_COMPUTE_ERROR_ON(graph == nullptr);
+
+    bool are_all_visited = true;
+    for(const auto &input_edge_id : node->input_edges())
+    {
+        if(input_edge_id != EmptyNodeID)
+        {
+            const Edge *input_edge = graph->edge(input_edge_id);
+            ARM_COMPUTE_ERROR_ON(input_edge == nullptr);
+            ARM_COMPUTE_ERROR_ON(input_edge->producer() == nullptr);
+            if(!visited[input_edge->producer_id()])
+            {
+                are_all_visited = false;
+                break;
+            }
+        }
+    }
+
+    return are_all_visited;
+}
+} // namespace detail
+
+/** Breadth first search traversal
+ *
+ * @param g Graph to traverse
+ *
+ * @return A vector with the node id traversal order
+ */
+inline std::vector<NodeID> bfs(Graph &g)
+{
+    std::vector<NodeID> bfs_order_vector;
+
+    // Created visited vector
+    std::vector<bool> visited(g.nodes().size(), false);
+
+    // Create BFS queue
+    std::list<NodeID> queue;
+
+    // Push inputs and mark as visited
+    for(auto &input : g.inputs())
+    {
+        if(input != EmptyNodeID)
+        {
+            visited[input] = true;
+            queue.push_back(input);
+        }
+    }
+
+    // Iterate over vector and edges
+    while(!queue.empty())
+    {
+        // Dequeue a node from queue and process
+        NodeID n = queue.front();
+        bfs_order_vector.push_back(n);
+        queue.pop_front();
+
+        const INode *node = g.node(n);
+        ARM_COMPUTE_ERROR_ON(node == nullptr);
+        for(const auto &eid : node->output_edges())
+        {
+            const Edge *e = g.edge(eid);
+            ARM_COMPUTE_ERROR_ON(e == nullptr);
+            if(!visited[e->consumer_id()] && detail::all_inputs_are_visited(e->consumer(), visited))
+            {
+                visited[e->consumer_id()] = true;
+                queue.push_back(e->consumer_id());
+            }
+        }
+    }
+
+    return bfs_order_vector;
+}
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_ALGORITHM_BFS_H__ */
diff --git a/arm_compute/graph/OperationRegistrar.h b/arm_compute/graph/backends/BackendRegistrar.h
similarity index 68%
rename from arm_compute/graph/OperationRegistrar.h
rename to arm_compute/graph/backends/BackendRegistrar.h
index ee171c3..f7f2f7f 100644
--- a/arm_compute/graph/OperationRegistrar.h
+++ b/arm_compute/graph/backends/BackendRegistrar.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,39 +21,41 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR
-#define ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR
+#ifndef ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__
+#define ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__
 
-#include "arm_compute/graph/OperationRegistry.h"
 #include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/backends/BackendRegistry.h"
 
-#include <string>
 #include <utility>
 
 namespace arm_compute
 {
 namespace graph
 {
+namespace backends
+{
 namespace detail
 {
-/** Helper class to statically register an operation */
+/** Helper class to statically register a backend */
 template <typename T>
-class OperationRegistrar final
+class BackendRegistrar final
 {
 public:
-    /** Add a new test case with the given name to the framework.
+    /** Add a new backend to the backend registry
      *
-     * @param[in] operation Operation type
+     * @param[in] target Execution target
      */
-    OperationRegistrar(OperationType operation);
+    BackendRegistrar(Target target);
 };
 
 template <typename T>
-inline OperationRegistrar<T>::OperationRegistrar(OperationType operation)
+inline BackendRegistrar<T>::BackendRegistrar(Target target)
 {
-    OperationRegistry::get().add_operation<T>(std::move(operation));
+    BackendRegistry::get().add_backend<T>(target);
 }
 } // namespace detail
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR */
\ No newline at end of file
+#endif /* ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__ */
\ No newline at end of file
diff --git a/arm_compute/graph/backends/BackendRegistry.h b/arm_compute/graph/backends/BackendRegistry.h
new file mode 100644
index 0000000..69114ed
--- /dev/null
+++ b/arm_compute/graph/backends/BackendRegistry.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_BACKEND_REGISTRY_H__
+#define __ARM_COMPUTE_GRAPH_BACKEND_REGISTRY_H__
+
+#include "arm_compute/graph/IDeviceBackend.h"
+#include "arm_compute/graph/Types.h"
+#include "support/ToolchainSupport.h"
+
+#include <map>
+#include <memory>
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** Registry holding all the supported backends */
+class BackendRegistry final
+{
+public:
+    /** Gets backend registry instance
+     *
+     * @return Backend registry instance
+     */
+    static BackendRegistry &get();
+    /** Finds a backend in the registry
+     *
+     * @param[in] target Backend target
+     *
+     * @return Pointer to the backend interface if found, else nullptr
+     */
+    IDeviceBackend *find_backend(Target target);
+    /** Checks if a backend for a given target exists
+     *
+     * @param[in] target Execution target
+     *
+     * @return True if exists else false
+     */
+    bool contains(Target target) const;
+    /** Backends accessor
+     *
+     * @return Map containing the registered backends
+     */
+    const std::map<Target, std::unique_ptr<IDeviceBackend>> &backends() const;
+    /** Registers a backend to the registry
+     *
+     * @param[in] target Execution target to register for
+     */
+    template <typename T>
+    void add_backend(Target target);
+
+private:
+    /** Default Constructor */
+    BackendRegistry();
+
+private:
+    std::map<Target, std::unique_ptr<IDeviceBackend>> _registered_backends;
+};
+
+template <typename T>
+inline void BackendRegistry::add_backend(Target target)
+{
+    _registered_backends[target] = support::cpp14::make_unique<T>();
+}
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_BACKEND_REGISTRY_H__ */
diff --git a/arm_compute/graph/backends/CL/CLDeviceBackend.h b/arm_compute/graph/backends/CL/CLDeviceBackend.h
new file mode 100644
index 0000000..ab39d0f
--- /dev/null
+++ b/arm_compute/graph/backends/CL/CLDeviceBackend.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_CLDEVICEBACKEND_H__
+#define __ARM_COMPUTE_GRAPH_CLDEVICEBACKEND_H__
+
+#include "arm_compute/graph/IDeviceBackend.h"
+
+#include "arm_compute/runtime/CL/CLBufferAllocator.h"
+#include "arm_compute/runtime/CL/CLTuner.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** OpenCL device backend */
+class CLDeviceBackend final : public IDeviceBackend
+{
+public:
+    /** Default Constructor */
+    CLDeviceBackend();
+    /** Destructor */
+    ~CLDeviceBackend();
+    /** Switchs on or off the kernel tuning
+     *
+     * @note When true the tuner set is used, if no tuner is set a new default one is created
+     *
+     * @param[in] enable_tuning Enables tuning if false else true
+     */
+    void set_kernel_tuning(bool enable_tuning);
+
+    // Inherited overridden methods
+    void initialize_backend() override;
+    void setup_backend_context(GraphContext &ctx) override;
+    bool                           is_backend_supported() override;
+    IAllocator                    *backend_allocator() override;
+    std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override;
+    std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override;
+    std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override;
+    Status validate_node(INode &node) override;
+    std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override;
+
+private:
+    CLTuner           _tuner;     /**< CL kernel tuner */
+    CLBufferAllocator _allocator; /**< CL buffer affinity allocator */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif //__ARM_COMPUTE_GRAPH_CLDEVICEBACKEND_H__
diff --git a/arm_compute/graph/nodes/ReshapeLayer.h b/arm_compute/graph/backends/CL/CLFunctionFactory.h
similarity index 62%
copy from arm_compute/graph/nodes/ReshapeLayer.h
copy to arm_compute/graph/backends/CL/CLFunctionFactory.h
index b727d33..6caca54 100644
--- a/arm_compute/graph/nodes/ReshapeLayer.h
+++ b/arm_compute/graph/backends/CL/CLFunctionFactory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,34 +21,37 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__
+#define __ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/runtime/IFunction.h"
+
+#include <memory>
 
 namespace arm_compute
 {
 namespace graph
 {
-/** Reshape layer node */
-class ReshapeLayer final : public INode
+// Forward declarations
+class INode;
+class GraphContext;
+
+namespace backends
+{
+/** Factory for generating OpenCL backend functions **/
+class CLFunctionFactory final
 {
 public:
-    /** Default constructor
+    /** Create a backend execution function depending on the node type
      *
-     * @param[in] shape Output shape
+     * @param[in] node Node to create the backend function for
+     * @param[in] ctx  Context to use
+     *
+     * @return Backend function
      */
-    ReshapeLayer(const TensorShape shape);
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    TensorShape _shape;
+    static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx);
 };
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ */
+#endif //__ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/backends/CL/CLNodeValidator.h
similarity index 67%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/backends/CL/CLNodeValidator.h
index b5d1bc5..9bd4842 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/backends/CL/CLNodeValidator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,32 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__
+#define __ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/core/Error.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+// Forward declarations
+class INode;
+
+namespace backends
+{
+class CLNodeValidator final
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Validate a node
+     *
+     * @param[in] node Node to validate
+     *
+     * @return An error status
+     */
+    static Status validate(INode *node);
 };
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif //__ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__
diff --git a/arm_compute/graph/backends/CL/CLSubTensorHandle.h b/arm_compute/graph/backends/CL/CLSubTensorHandle.h
new file mode 100644
index 0000000..0c515a1
--- /dev/null
+++ b/arm_compute/graph/backends/CL/CLSubTensorHandle.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_CLSUBTENSORHANDLE_H__
+#define __ARM_COMPUTE_GRAPH_CLSUBTENSORHANDLE_H__
+
+#include "arm_compute/graph/ITensorHandle.h"
+
+#include "arm_compute/runtime/CL/CLSubTensor.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** OpenCL Sub-Tensor handle interface object **/
+class CLSubTensorHandle final : public ITensorHandle
+{
+public:
+    /** Default constructor
+     *
+     * @param[in] parent_handle Parent tensor handle
+     * @param[in] shape         Sub-Tensor shape
+     * @param[in] coords        Starting coordinates
+     * @param[in] extend_parent Extends parent shape if true
+     */
+    CLSubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent = false);
+    /** Destructor: free the tensor's memory */
+    ~CLSubTensorHandle() = default;
+    /** Allow instances of this class to be move constructed */
+    CLSubTensorHandle(CLSubTensorHandle &&) = default;
+    /** Allow instances of this class to be moved */
+    CLSubTensorHandle &operator=(CLSubTensorHandle &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    CLSubTensorHandle(const CLSubTensorHandle &) = delete;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    CLSubTensorHandle &operator=(const CLSubTensorHandle &) = delete;
+
+    // Inherited overridden methods
+    void allocate() override;
+    void free() override;
+    void manage(IMemoryGroup *mg) override;
+    void map(bool blocking) override;
+    void                        unmap() override;
+    void                        release_if_unused() override;
+    arm_compute::ITensor       &tensor() override;
+    const arm_compute::ITensor &tensor() const override;
+    ITensorHandle              *parent_handle() override;
+    bool                        is_subtensor() const override;
+    Target                      target() const override;
+
+private:
+    arm_compute::CLSubTensor _sub_tensor;    /**< Backend Sub-Tensor */
+    ITensorHandle           *_parent_handle; /**< Parent handle */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_CLSUBTENSORHANDLE_H__ */
diff --git a/arm_compute/graph/backends/CL/CLTensorHandle.h b/arm_compute/graph/backends/CL/CLTensorHandle.h
new file mode 100644
index 0000000..2399732
--- /dev/null
+++ b/arm_compute/graph/backends/CL/CLTensorHandle.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_CLTENSORHANDLE_H__
+#define __ARM_COMPUTE_GRAPH_CLTENSORHANDLE_H__
+
+#include "arm_compute/graph/ITensorHandle.h"
+
+#include "arm_compute/runtime/CL/CLTensor.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** OpenCL Tensor handle interface object **/
+class CLTensorHandle final : public ITensorHandle
+{
+public:
+    /** Default Constructor
+     *
+     * @param[in] info Tensor metadata
+     */
+    CLTensorHandle(const ITensorInfo &info);
+    /** Destructor: free the tensor's memory */
+    ~CLTensorHandle() = default;
+    /** Allow instances of this class to be move constructed */
+    CLTensorHandle(CLTensorHandle &&) = default;
+    /** Allow instances of this class to be moved */
+    CLTensorHandle &operator=(CLTensorHandle &&) = default;
+
+    // Inherited overridden methods
+    void allocate() override;
+    void free() override;
+    void manage(IMemoryGroup *mg) override;
+    void map(bool blocking) override;
+    void                        unmap() override;
+    void                        release_if_unused() override;
+    arm_compute::ITensor       &tensor() override;
+    const arm_compute::ITensor &tensor() const override;
+    ITensorHandle              *parent_handle() override;
+    bool                        is_subtensor() const override;
+    Target                      target() const override;
+
+private:
+    arm_compute::CLTensor _tensor; /**< Backend Tensor */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_CLTENSORHANDLE_H__ */
diff --git a/arm_compute/graph/backends/GLES/GCDeviceBackend.h b/arm_compute/graph/backends/GLES/GCDeviceBackend.h
new file mode 100644
index 0000000..dc0e2b0
--- /dev/null
+++ b/arm_compute/graph/backends/GLES/GCDeviceBackend.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_GCDEVICEBACKEND_H__
+#define __ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H__
+
+#include "arm_compute/graph/IDeviceBackend.h"
+
+#include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** GLES Compute device backend */
+class GCDeviceBackend final : public IDeviceBackend
+{
+public:
+    /** Default Constructor */
+    GCDeviceBackend();
+
+    // Inherited overridden methods
+    void initialize_backend() override;
+    void setup_backend_context(GraphContext &ctx) override;
+    bool                           is_backend_supported() override;
+    IAllocator                    *backend_allocator() override;
+    std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override;
+    std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override;
+    std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override;
+    Status validate_node(INode &node) override;
+    std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override;
+
+private:
+    GCBufferAllocator _allocator; /**< GLES buffer affinity allocator */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif //__ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H__
diff --git a/arm_compute/graph/nodes/ReshapeLayer.h b/arm_compute/graph/backends/GLES/GCFunctionFactory.h
similarity index 62%
copy from arm_compute/graph/nodes/ReshapeLayer.h
copy to arm_compute/graph/backends/GLES/GCFunctionFactory.h
index b727d33..c819c03 100644
--- a/arm_compute/graph/nodes/ReshapeLayer.h
+++ b/arm_compute/graph/backends/GLES/GCFunctionFactory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,34 +21,37 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__
+#define __ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/runtime/IFunction.h"
+
+#include <memory>
 
 namespace arm_compute
 {
 namespace graph
 {
-/** Reshape layer node */
-class ReshapeLayer final : public INode
+// Forward declarations
+class INode;
+class GraphContext;
+
+namespace backends
+{
+/** Factory for generating GLES compute backend functions **/
+class GCFunctionFactory final
 {
 public:
-    /** Default constructor
+    /** Create a backend execution function depending on the node type
      *
-     * @param[in] shape Output shape
+     * @param[in] node Node to create the backend function for
+     * @param[in] ctx  Context to use
+     *
+     * @return Backend function
      */
-    ReshapeLayer(const TensorShape shape);
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    TensorShape _shape;
+    static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx);
 };
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ */
+#endif //__ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/backends/GLES/GCNodeValidator.h
similarity index 67%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/backends/GLES/GCNodeValidator.h
index b5d1bc5..6fdfbdd 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/backends/GLES/GCNodeValidator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,32 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__
+#define __ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/core/Error.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+// Forward declarations
+class INode;
+
+namespace backends
+{
+class GCNodeValidator final
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Validate a node
+     *
+     * @param[in] node Node to validate
+     *
+     * @return An error status
+     */
+    static Status validate(INode *node);
 };
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif //__ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__
diff --git a/arm_compute/graph/backends/GLES/GCTensorHandle.h b/arm_compute/graph/backends/GLES/GCTensorHandle.h
new file mode 100644
index 0000000..29b0319
--- /dev/null
+++ b/arm_compute/graph/backends/GLES/GCTensorHandle.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_GCTENSORHANDLE_H__
+#define __ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H__
+
+#include "arm_compute/graph/ITensorHandle.h"
+
+#include "arm_compute/runtime/GLES_COMPUTE/GCTensor.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** GLES compute tensor handle interface object **/
+class GCTensorHandle final : public ITensorHandle
+{
+public:
+    /** Default Constructor
+     *
+     * @param[in] info Tensor metadata
+     */
+    GCTensorHandle(const ITensorInfo &info);
+    /** Destructor: free the tensor's memory */
+    ~GCTensorHandle() = default;
+    /** Allow instances of this class to be move constructed */
+    GCTensorHandle(GCTensorHandle &&) = default;
+    /** Allow instances of this class to be moved */
+    GCTensorHandle &operator=(GCTensorHandle &&) = default;
+
+    // Inherited overridden methods
+    void allocate() override;
+    void free() override;
+    void manage(IMemoryGroup *mg) override;
+    void map(bool blocking) override;
+    void                        unmap() override;
+    void                        release_if_unused() override;
+    arm_compute::ITensor       &tensor() override;
+    const arm_compute::ITensor &tensor() const override;
+    ITensorHandle              *parent_handle() override;
+    bool                        is_subtensor() const override;
+    Target                      target() const override;
+
+private:
+    arm_compute::GCTensor _tensor; /**< Backend Tensor */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H__ */
diff --git a/arm_compute/graph/backends/NEON/NEDeviceBackend.h b/arm_compute/graph/backends/NEON/NEDeviceBackend.h
new file mode 100644
index 0000000..c1e2e0c
--- /dev/null
+++ b/arm_compute/graph/backends/NEON/NEDeviceBackend.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_NEDEVICEBACKEND_H__
+#define __ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H__
+
+#include "arm_compute/graph/IDeviceBackend.h"
+
+#include "arm_compute/runtime/Allocator.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** NEON device backend */
+class NEDeviceBackend final : public IDeviceBackend
+{
+public:
+    NEDeviceBackend();
+
+    // Inherited overridden methods
+    void initialize_backend() override;
+    void setup_backend_context(GraphContext &ctx) override;
+    bool                           is_backend_supported() override;
+    IAllocator                    *backend_allocator() override;
+    std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override;
+    std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override;
+    std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override;
+    Status validate_node(INode &node) override;
+    std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override;
+
+private:
+    Allocator _allocator; /**< NEON backend allocator */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif //__ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H__
diff --git a/arm_compute/graph/nodes/ReshapeLayer.h b/arm_compute/graph/backends/NEON/NEFunctionFactory.h
similarity index 62%
copy from arm_compute/graph/nodes/ReshapeLayer.h
copy to arm_compute/graph/backends/NEON/NEFunctionFactory.h
index b727d33..1143c29 100644
--- a/arm_compute/graph/nodes/ReshapeLayer.h
+++ b/arm_compute/graph/backends/NEON/NEFunctionFactory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,34 +21,37 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_NEFUNCTIONFACTORY_H__
+#define __ARM_COMPUTE_GRAPH_NEFUNCTIONFACTORY_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/runtime/IFunction.h"
+
+#include <memory>
 
 namespace arm_compute
 {
 namespace graph
 {
-/** Reshape layer node */
-class ReshapeLayer final : public INode
+// Forward declarations
+class INode;
+class GraphContext;
+
+namespace backends
+{
+/** Factory for generating NEON backend functions **/
+class NEFunctionFactory final
 {
 public:
-    /** Default constructor
+    /** Create a backend execution function depending on the node type
      *
-     * @param[in] shape Output shape
+     * @param[in] node Node to create the backend function for
+     * @param[in] ctx  Context to use
+     *
+     * @return Backend function
      */
-    ReshapeLayer(const TensorShape shape);
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    TensorShape _shape;
+    static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx);
 };
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ */
+#endif //__ARM_COMPUTE_GRAPH_NEFUNCTIONFACTORY_H__
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/backends/NEON/NENodeValidator.h
similarity index 67%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/backends/NEON/NENodeValidator.h
index b5d1bc5..38f58a9 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/backends/NEON/NENodeValidator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,32 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_NENODEVALIDATOR_H__
+#define __ARM_COMPUTE_GRAPH_NENODEVALIDATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/core/Error.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+// Forward declarations
+class INode;
+
+namespace backends
+{
+class NENodeValidator final
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Validate a node
+     *
+     * @param[in] node Node to validate
+     *
+     * @return An error status
+     */
+    static Status validate(INode *node);
 };
+} // namespace backends
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif //__ARM_COMPUTE_GRAPH_NENODEVALIDATOR_H__
diff --git a/arm_compute/graph/backends/NEON/NESubTensorHandle.h b/arm_compute/graph/backends/NEON/NESubTensorHandle.h
new file mode 100644
index 0000000..101d3e6
--- /dev/null
+++ b/arm_compute/graph/backends/NEON/NESubTensorHandle.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_NESUBTENSORHANDLE_H__
+#define __ARM_COMPUTE_GRAPH_NESUBTENSORHANDLE_H__
+
+#include "arm_compute/graph/ITensorHandle.h"
+
+#include "arm_compute/runtime/SubTensor.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** NEON Sub-Tensor handle interface object **/
+class NESubTensorHandle final : public ITensorHandle
+{
+public:
+    /** Default constructor
+     *
+     * @param[in] parent_handle Parent tensor handle
+     * @param[in] shape         Sub-Tensor shape
+     * @param[in] coords        Starting coordinates
+     * @param[in] extend_parent Extends parent shape if true
+     */
+    NESubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent = false);
+    /** Destructor: free the tensor's memory */
+    ~NESubTensorHandle() = default;
+    /** Allow instances of this class to be move constructed */
+    NESubTensorHandle(NESubTensorHandle &&) = default;
+    /** Allow instances of this class to be moved */
+    NESubTensorHandle &operator=(NESubTensorHandle &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    NESubTensorHandle(const NESubTensorHandle &) = delete;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    NESubTensorHandle &operator=(const NESubTensorHandle &) = delete;
+
+    // Inherited overridden methods
+    void allocate() override;
+    void free() override;
+    void manage(IMemoryGroup *mg) override;
+    void map(bool blocking) override;
+    void                        unmap() override;
+    void                        release_if_unused() override;
+    arm_compute::ITensor       &tensor() override;
+    const arm_compute::ITensor &tensor() const override;
+    ITensorHandle              *parent_handle() override;
+    bool                        is_subtensor() const override;
+    Target                      target() const override;
+
+private:
+    arm_compute::SubTensor _sub_tensor;    /**< Backend Sub-Tensor */
+    ITensorHandle         *_parent_handle; /**< Parent handle */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_NESUBTENSORHANDLE_H__ */
diff --git a/arm_compute/graph/backends/NEON/NETensorHandle.h b/arm_compute/graph/backends/NEON/NETensorHandle.h
new file mode 100644
index 0000000..150e0c9
--- /dev/null
+++ b/arm_compute/graph/backends/NEON/NETensorHandle.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_NETENSORHANDLE_H__
+#define __ARM_COMPUTE_GRAPH_NETENSORHANDLE_H__
+
+#include "arm_compute/graph/ITensorHandle.h"
+
+#include "arm_compute/runtime/Tensor.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** NEON Tensor handle interface object **/
+class NETensorHandle final : public ITensorHandle
+{
+public:
+    /** Default Constructor
+     *
+     * @param[in] info Tensor metadata
+     */
+    NETensorHandle(const ITensorInfo &info);
+    /** Destructor: free the tensor's memory */
+    ~NETensorHandle() = default;
+    /** Allow instances of this class to be move constructed */
+    NETensorHandle(NETensorHandle &&) = default;
+    /** Allow instances of this class to be moved */
+    NETensorHandle &operator=(NETensorHandle &&) = default;
+
+    // Inherited overridden methods
+    void allocate() override;
+    void free() override;
+    void manage(IMemoryGroup *mg) override;
+    void map(bool blocking) override;
+    void                        unmap() override;
+    void                        release_if_unused() override;
+    arm_compute::ITensor       &tensor() override;
+    const arm_compute::ITensor &tensor() const override;
+    ITensorHandle              *parent_handle() override;
+    bool                        is_subtensor() const override;
+    Target                      target() const override;
+
+private:
+    arm_compute::Tensor _tensor; /**< Backend Tensor */
+};
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_NETENSORHANDLE_H__ */
diff --git a/arm_compute/graph/backends/Utils.h b/arm_compute/graph/backends/Utils.h
new file mode 100644
index 0000000..c7a50d9
--- /dev/null
+++ b/arm_compute/graph/backends/Utils.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_BACKENDS_UTILS_H__
+#define __ARM_COMPUTE_GRAPH_BACKENDS_UTILS_H__
+
+#include "arm_compute/graph/GraphContext.h"
+#include "arm_compute/runtime/IMemoryManager.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+/** Creates and configures a named function
+ *
+ * @param[in] name Name of the function
+ * @param[in] args Function arguments
+ *
+ * @return  A configured backend function
+ */
+template <typename FunctionType, typename FunctionNameType, typename... ParameterType>
+std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_function(FunctionNameType name, ParameterType... args)
+{
+    auto f = arm_compute::support::cpp14::make_unique<FunctionType>();
+    f->configure(std::forward<ParameterType>(args)...);
+    return std::make_pair(std::move(f), name);
+}
+
+/** Creates and configures a named function
+ *
+ * @param[in] name Name of the function
+ * @param[in] mm   Memory manager to use
+ * @param[in] args Function arguments
+ *
+ * @return  A configured backend function
+ */
+template <typename FunctionType, typename FunctionNameType, typename MemoryManagerType, typename... ParameterType>
+std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_memory_managed_function(FunctionNameType name,
+                                                                                                          MemoryManagerType mm,
+                                                                                                          ParameterType... args)
+{
+    auto f = arm_compute::support::cpp14::make_unique<FunctionType>(mm);
+    f->configure(std::forward<ParameterType>(args)...);
+    return std::make_pair(std::move(f), name);
+}
+
+/** Checks if an operation is in place
+ *
+ * @param[in] input  Pointer to input
+ * @param[in] output Pointer to output
+ *
+ * @return True if output is nullptr or input is equal to the output, else false
+ */
+inline bool is_in_place_operation(void *input, void *output)
+{
+    return (output == nullptr) || (input == output);
+}
+
+/** Returns the memory manager for a given target
+ *
+ * @param[in] ctx    Graph context containing memory management metadata
+ * @param[in] target Target to retrieve the memory manager from
+ *
+ * @return The memory manager for the given target else false
+ */
+inline std::shared_ptr<IMemoryManager> get_memory_manager(GraphContext &ctx, Target target)
+{
+    bool enabled = ctx.config().use_function_memory_manager && (ctx.memory_management_ctx(target) != nullptr);
+    return enabled ? ctx.memory_management_ctx(target)->intra_mm : nullptr;
+}
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+
+#endif /* __ARM_COMPUTE_GRAPH_BACKENDS_UTILS_H__ */
diff --git a/arm_compute/graph/backends/ValidateHelpers.h b/arm_compute/graph/backends/ValidateHelpers.h
new file mode 100644
index 0000000..e10e994
--- /dev/null
+++ b/arm_compute/graph/backends/ValidateHelpers.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H__
+#define __ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H__
+
+#include "arm_compute/graph/Logger.h"
+#include "arm_compute/graph/Tensor.h"
+#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/nodes/Nodes.h"
+
+#include "arm_compute/core/Error.h"
+#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/ITensorInfo.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace backends
+{
+namespace detail
+{
+/** Returns backing tensor info of a given tensor
+ *
+ * @param[in] tensor Tensor to extract the backing tensor from
+ *
+ * @return Backing tensor tensor info if present else nullptr
+ */
+inline arm_compute::ITensorInfo *get_backing_tensor_info(arm_compute::graph::Tensor *tensor)
+{
+    return ((tensor == nullptr) || (tensor->handle() == nullptr)) ? nullptr : tensor->handle()->tensor().info();
+}
+
+/** Validates a Convolution layer node
+ *
+ * @tparam ConvolutionLayer          Default Convolution layer function type
+ * @tparam DirectConvolutionLayer    Direct Convolution layer function type
+ * @tparam GEMMConvolutionLayer      GEMM Convolution layer function type
+ * @tparam WinogradConvolutionLayer  Winograd Convolution layer function type
+ *
+ * @param[in] node Node to validate
+ *
+ * @return Status
+ */
+template <typename ConvolutionLayer, typename DirectConvolutionLayer, typename GEMMConvolutionLayer, typename WinogradConvolutionLayer>
+Status validate_convolution_layer(ConvolutionLayerNode &node)
+{
+    ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl);
+    ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3);
+    ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1);
+
+    // Extract IO and info
+    arm_compute::ITensorInfo *input   = get_backing_tensor_info(node.input(0));
+    arm_compute::ITensorInfo *weights = get_backing_tensor_info(node.input(1));
+    arm_compute::ITensorInfo *biases  = get_backing_tensor_info(node.input(2));
+    arm_compute::ITensorInfo *output  = get_backing_tensor_info(node.output(0));
+
+    if(is_data_type_quantized_asymmetric(input->data_type()))
+    {
+        biases->set_data_type(DataType::S32);
+    }
+
+    const PadStrideInfo     conv_info      = node.convolution_info();
+    const ConvolutionMethod conv_algorithm = node.convolution_method();
+
+    // Validate function
+    Status status{};
+    switch(conv_algorithm)
+    {
+        case ConvolutionMethod::DIRECT:
+            status = DirectConvolutionLayer::validate(input, weights, biases, output, conv_info);
+            break;
+        case ConvolutionMethod::GEMM:
+            status = GEMMConvolutionLayer::validate(input, weights, biases, output, conv_info);
+            break;
+        case ConvolutionMethod::WINOGRAD:
+            status = WinogradConvolutionLayer::validate(input, weights, biases, output, conv_info /*, fast_math*/);
+            break;
+        case ConvolutionMethod::DEFAULT:
+            status = ConvolutionLayer::validate(input, weights, biases, output, conv_info);
+            break;
+        default:
+            break;
+    }
+
+    // If validation fails try the Default approach
+    if(!bool(status))
+    {
+        status = ConvolutionLayer::validate(input, weights, biases, output, conv_info /*, fast_math*/);
+        if(bool(status))
+        {
+            ARM_COMPUTE_LOG_GRAPH_INFO("Switched ConvolutionLayer method of node with ID : "
+                                       << node.id() << " and Name: " << node.name() << std::endl);
+            node.set_convolution_method(ConvolutionMethod::DEFAULT);
+        }
+    }
+
+    return status;
+}
+
+/** Validates a Depthwise Convolution layer node
+ *
+ * @tparam DepthwiseConvolutionLayer    Default Depthwise Convolution layer type
+ * @tparam DepthwiseConvolutionLayer3x3 Optimized 3x3 Depthwise Convolution layer type
+ *
+ * @param[in] node Node to validate
+ *
+ * @return Status
+ */
+template <typename DepthwiseConvolutionLayer, typename DepthwiseConvolutionLayer3x3>
+Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node)
+{
+    ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl);
+    ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3);
+    ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1);
+
+    // Extract IO and info
+    arm_compute::ITensorInfo        *weights       = detail::get_backing_tensor_info(node.input(1));
+    const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method();
+    ARM_COMPUTE_ERROR_ON(weights == nullptr);
+
+    // Validate function
+    if((dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) && (weights->tensor_shape()[get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::WIDTH)] != 3))
+    {
+        ARM_COMPUTE_LOG_GRAPH_INFO("Switched DepthwiseConvolutionLayer method of node with ID : "
+                                   << node.id() << " and Name: " << node.name() << std::endl);
+        node.set_depthwise_convolution_method(DepthwiseConvolutionMethod::DEFAULT);
+    }
+
+    return Status{};
+}
+} // namespace detail
+} // namespace backends
+} // namespace graph
+} // namespace arm_compute
+
+#endif /* __ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h
similarity index 61%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h
index b5d1bc5..b7424c8 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/detail/CrossLayerMemoryManagerHelpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,32 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_DETAIL_CROSS_LAYER_MEMORY_MANAGER_HELPERS_H__
+#define __ARM_COMPUTE_GRAPH_DETAIL_CROSS_LAYER_MEMORY_MANAGER_HELPERS_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include <vector>
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+// Forward declarations
+class Graph;
+class GraphContext;
+class ExecutionWorkload;
+class ITransMemoryManager;
+class ITensorHandle;
+
+namespace detail
 {
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
+/** Configures transition manager and execution workload
+ *
+ * @param[in] g        Graph to configure
+ * @param[in] ctx      Graph context
+ * @param[in] workload Workload to configure
+ */
+void configure_transition_manager(Graph &g, GraphContext &ctx, ExecutionWorkload &workload);
+} // namespace detail
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_DETAIL_CROSS_LAYER_MEMORY_MANAGER_HELPERS_H__ */
diff --git a/arm_compute/graph/detail/ExecutionHelpers.h b/arm_compute/graph/detail/ExecutionHelpers.h
new file mode 100644
index 0000000..27cae4b
--- /dev/null
+++ b/arm_compute/graph/detail/ExecutionHelpers.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_DETAIL_EXECUTION_HELPERS_H__
+#define __ARM_COMPUTE_GRAPH_DETAIL_EXECUTION_HELPERS_H__
+
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class Graph;
+class GraphContext;
+class ExecutionWorkload;
+class Tensor;
+class INode;
+
+namespace detail
+{
+/** Initializes the available backends **/
+void default_initialize_backends();
+/** Validates all nodes
+ *
+ * @param[in] g Graph to validate
+ */
+void validate_all_nodes(Graph &g);
+/** Configures all nodes of a graph
+ *
+ * @param[in] g Graph to configure
+ */
+void configure_all_tensors(Graph &g);
+/** Allocates all input tensors of a node.
+ *
+ * @param[in] node Node to allocate the input tensor of
+ */
+void allocate_all_input_tensors(INode &node);
+/** Allocates all output tensors of a node.
+ *
+ * @param[in] node Node to allocate the output tensor of
+ */
+void allocate_all_output_tensors(INode &node);
+/** Allocates const tensor of a given graph
+ *
+ * @param[in] g Graph to allocate the tensors
+ */
+void allocate_const_tensors(Graph &g);
+/** Allocates all tensors of a graph
+ *
+ * @param[in] g Graph to allocate the tensors
+ */
+void allocate_all_tensors(Graph &g);
+/** Configures all nodes of graph
+ *
+ * @param[in] g   Graph to configure the nodes
+ * @param[in] ctx Graph context to use
+ *
+ * @return The execution workload
+ */
+ExecutionWorkload configure_all_nodes(Graph &g, GraphContext &ctx);
+/** Release the memory of all unused const nodes
+ *
+ * @param[in] g Graph to release the memory from
+ */
+void release_unused_tensors(Graph &g);
+/** Calls accessor of a given tensor
+ *
+ * @param[in] tensor The tensor of which the accessor should be called
+ */
+void call_tensor_accessor(Tensor *tensor);
+/** Call all const node accessors
+ *
+ * @param[in] g Graph containing the const nodes
+ */
+void call_all_const_node_accessors(Graph &g);
+/** Call all input node accessors
+ *
+ * @param[in] workload Workload to execute
+ */
+void call_all_input_node_accessors(ExecutionWorkload &workload);
+/** Call all output node accessors
+ *
+ * @param[in] workload Workload to execute
+ */
+void call_all_output_node_accessors(ExecutionWorkload &workload);
+/** Prepares all tasks for execution
+ *
+ * @param[in] workload Workload to prepare
+ */
+void prepare_all_tasks(ExecutionWorkload &workload);
+/** Executes all tasks of a workload
+ *
+ * @param[in] workload Workload to execute
+ */
+void call_all_tasks(ExecutionWorkload &workload);
+} // namespace detail
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_DETAIL_EXECUTION_HELPERS_H__ */
diff --git a/arm_compute/graph/NodeParameter.h b/arm_compute/graph/frontend/ILayer.h
similarity index 60%
rename from arm_compute/graph/NodeParameter.h
rename to arm_compute/graph/frontend/ILayer.h
index 9d3823d..f7caaea 100644
--- a/arm_compute/graph/NodeParameter.h
+++ b/arm_compute/graph/frontend/ILayer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,54 +21,55 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__
-#define __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__
-
-#include <ostream>
-#include <string>
+#ifndef __ARM_COMPUTE_GRAPH_ILAYER_H__
+#define __ARM_COMPUTE_GRAPH_ILAYER_H__
 
 namespace arm_compute
 {
 namespace graph
 {
-/**Node Parameter Empty base class */
-class NodeParameterBase
+namespace frontend
 {
-};
+// Forward declarations
+class IStream;
 
-/** Template parameter implementation */
-template <typename T>
-class NodeParameter : public NodeParameterBase
+/** ILayer interface */
+class ILayer
 {
 public:
-    /** Default Constructor
+    /** Default destructor */
+    virtual ~ILayer() = default;
+    /** Create layer and add to the given stream.
      *
-     * @param[in] name Paremeter name
-     * @param[in] val  Parameter value
-     */
-    NodeParameter(std::string name, T val)
-        : _name(name), _val(val) {};
-    /** Returns parameter's name
+     * @param[in] s Stream to add layer to.
      *
-     * @return the name of the parameter
+     * @return ID of the created node.
      */
-    std::string name() const
+    virtual NodeID create_layer(IStream &s) = 0;
+    /** Sets the name of the layer
+     *
+     * @param[in] name Name of the layer
+     *
+     * @return The layer object
+     */
+    ILayer &set_name(std::string name)
+    {
+        _name = name;
+        return *this;
+    }
+    /** Layer name accessor
+     *
+     * @return Returns the name of the layer
+     */
+    const std::string &name() const
     {
         return _name;
     }
-    /** Returns parameter's value
-     *
-     * @return the value of the parameter
-     */
-    T value()
-    {
-        return _val;
-    }
 
 private:
-    std::string _name;
-    T           _val;
+    std::string _name = {};
 };
+} // namespace frontend
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_ILAYER_H__ */
diff --git a/arm_compute/graph/frontend/IStream.h b/arm_compute/graph/frontend/IStream.h
new file mode 100644
index 0000000..13995f9
--- /dev/null
+++ b/arm_compute/graph/frontend/IStream.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_ISTREAM_H__
+#define __ARM_COMPUTE_GRAPH_ISTREAM_H__
+
+#include "arm_compute/graph/frontend/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class Graph;
+
+namespace frontend
+{
+// Forward declarations
+class ILayer;
+
+/** Stream interface **/
+class IStream
+{
+public:
+    virtual ~IStream() = default;
+    /** Adds a layer to the stream
+     *
+     * @param[in] layer Layer to add
+     */
+    virtual void add_layer(ILayer &layer) = 0;
+    /** Returns the underlying graph
+     *
+     * @return Underlying graph
+     */
+    virtual Graph &graph() = 0;
+    /** Returns the underlying graph
+     *
+     * @return Underlying graph
+     */
+    virtual const Graph &graph() const = 0;
+    /** Returns the tail node of the Stream
+     *
+     * @return Tail Node ID
+     */
+    NodeID tail_node()
+    {
+        return _tail_node;
+    }
+    /** Returns the stream hints that are currently used
+     *
+     * @return Stream hints
+     */
+    StreamHints &hints()
+    {
+        return _hints;
+    }
+    /** Forwards tail of stream to a given nid
+     *
+     * @param[in] nid NodeID of the updated tail node
+     */
+    void forward_tail(NodeID nid)
+    {
+        _tail_node = (nid != NullTensorID) ? nid : _tail_node;
+    }
+
+protected:
+    StreamHints _hints     = {};              /**< Execution and algorithmic hints */
+    NodeID      _tail_node = { EmptyNodeID }; /**< NodeID pointing to the last(tail) node of the graph */
+};
+} // namespace frontend
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_ISTREAM_H__ */
diff --git a/arm_compute/graph/frontend/IStreamOperators.h b/arm_compute/graph/frontend/IStreamOperators.h
new file mode 100644
index 0000000..4d680f9
--- /dev/null
+++ b/arm_compute/graph/frontend/IStreamOperators.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_ISTREAM_OPERATORS_H__
+#define __ARM_COMPUTE_GRAPH_ISTREAM_OPERATORS_H__
+
+#include "arm_compute/graph/frontend/IStream.h"
+#include "arm_compute/graph/frontend/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace frontend
+{
+// Forward declarations
+class ILayer;
+
+/** Overloaded stream operator to add a node to the graph
+ *
+ * @param[in, out] s     Stream to add the tensor
+ * @param[in]      layer Layer to be added
+ *
+ * @return Updated stream
+ */
+inline IStream &operator<<(IStream &s, ILayer &&layer)
+{
+    s.add_layer(layer);
+    return s;
+}
+/** Overloaded stream operator to add a node to the graph
+ *
+ * @param[in, out] s     Stream to add the tensor
+ * @param[in]      layer Layer to be added
+ *
+ * @return Updated stream
+ */
+inline IStream &operator<<(IStream &s, ILayer &layer)
+{
+    s.add_layer(layer);
+    return s;
+}
+/** Overloaded stream operator to provide a target hint to the graph
+ *
+ * @param[in, out] s           Stream to provide the hint to
+ * @param[in]      target_hint Target hint to be considered
+ *
+ * @return Updated stream
+ */
+inline IStream &operator<<(IStream &s, Target target_hint)
+{
+    s.hints().target_hint = target_hint;
+    return s;
+}
+/** Overloaded stream operator to provide a convolution method hint to the graph
+ *
+ * @param[in, out] s                       Stream to provide the hint to
+ * @param[in]      convolution_method_hint Convolution method hint to be considered
+ *
+ * @return Updated stream
+ */
+inline IStream &operator<<(IStream &s, ConvolutionMethod convolution_method_hint)
+{
+    s.hints().convolution_method_hint = convolution_method_hint;
+    return s;
+}
+/** Overloaded stream operator to provide a depthwise convolution method hint to the graph
+ *
+ * @param[in, out] s                                 Stream to provide the hint to
+ * @param[in]      depthwise_convolution_method_hint Depthwise Convolution method hint to be considered
+ *
+ * @return Updated stream
+ */
+inline IStream &operator<<(IStream &s, DepthwiseConvolutionMethod depthwise_convolution_method_hint)
+{
+    s.hints().depthwise_convolution_method_hint = depthwise_convolution_method_hint;
+    return s;
+}
+/** Overloaded stream operator to provide a fast math hint to the graph
+ *
+ * @param[in, out] s              Stream to provide the hint to
+ * @param[in]      fast_math_hint Convolution method hint to be considered
+ *
+ * @return Updated stream
+ */
+inline IStream &operator<<(IStream &s, FastMathHint fast_math_hint)
+{
+    s.hints().fast_math_hint = fast_math_hint;
+    return s;
+}
+} // namespace frontend
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_ISTREAM_OPERATORS_H__ */
diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h
new file mode 100644
index 0000000..a976844
--- /dev/null
+++ b/arm_compute/graph/frontend/Layers.h
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_LAYERS_H__
+#define __ARM_COMPUTE_GRAPH_LAYERS_H__
+
+#include "arm_compute/graph/GraphBuilder.h"
+#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/frontend/ILayer.h"
+#include "arm_compute/graph/frontend/IStream.h"
+#include "arm_compute/graph/frontend/SubStream.h"
+
+#include "arm_compute/core/utils/misc/Utility.h"
+
+#include <memory>
+#include <string>
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace frontend
+{
+/** Input Layer */
+class InputLayer final : public ILayer
+{
+public:
+    /** Construct an input layer.
+     *
+     * @param[in] desc     Description of input tensor.
+     * @param[in] accessor Accessor to get input tensor data from.
+     */
+    InputLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor)
+        : _desc(desc), _accessor(std::move(accessor))
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams common_params = { name(), s.hints().target_hint };
+        return GraphBuilder::add_input_node(s.graph(), common_params, _desc, std::move(_accessor));
+    }
+
+private:
+    TensorDescriptor    _desc;
+    ITensorAccessorUPtr _accessor;
+};
+
+/** Output Layer */
+class OutputLayer final : public ILayer
+{
+public:
+    /** Construct an output layer.
+     *
+     * @param[in] accessor Accessor to give output tensor data to.
+     */
+    OutputLayer(ITensorAccessorUPtr accessor)
+        : _accessor(std::move(accessor))
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_output_node(s.graph(), common_params, input, std::move(_accessor));
+    }
+
+private:
+    ITensorAccessorUPtr _accessor;
+};
+
+/** Activation Layer */
+class ActivationLayer final : public ILayer
+{
+public:
+    /** Construct an activation layer.
+     *
+     * @param[in] act_info Activation information
+     */
+    ActivationLayer(ActivationLayerInfo act_info)
+        : _act_info(act_info)
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_activation_node(s.graph(), common_params, input, _act_info);
+    }
+
+private:
+    ActivationLayerInfo _act_info;
+};
+
+/** Batchnormalization Layer */
+class BatchNormalizationLayer final : public ILayer
+{
+public:
+    /** Construct a batch normalization layer.
+     *
+     * @param[in] mean    Accessor to get mean tensor data from.
+     * @param[in] var     Accessor to get var tensor data from.
+     * @param[in] gamma   (Optional) Accessor to get gamma tensor data from. Default: nullptr.
+     * @param[in] beta    (Optional) Accessor to get beta tensor data from. Default: nullptr.
+     * @param[in] epsilon (Optional) Epsilon value. Default: 0.001.
+     */
+    BatchNormalizationLayer(ITensorAccessorUPtr mean,
+                            ITensorAccessorUPtr var,
+                            ITensorAccessorUPtr gamma   = nullptr,
+                            ITensorAccessorUPtr beta    = nullptr,
+                            float               epsilon = 0.001f)
+        : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon)
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        ARM_COMPUTE_ERROR_ON(_mean == nullptr);
+        ARM_COMPUTE_ERROR_ON(_var == nullptr);
+
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_batch_normalization_node(s.graph(), common_params, input, _epsilon,
+                                                          std::move(_mean), std::move(_var), std::move(_beta), std::move(_gamma));
+    }
+
+private:
+    ITensorAccessorUPtr _mean;
+    ITensorAccessorUPtr _var;
+    ITensorAccessorUPtr _gamma;
+    ITensorAccessorUPtr _beta;
+    float               _epsilon;
+};
+
+/** Convolution Layer */
+class ConvolutionLayer final : public ILayer
+{
+public:
+    /** Construct a convolution layer.
+     *
+     * @param[in] conv_width         Convolution width.
+     * @param[in] conv_height        Convolution height.
+     * @param[in] ofm                Output feature map.
+     * @param[in] weights            Accessor to get kernel weights from.
+     * @param[in] bias               Accessor to get kernel bias from.
+     * @param[in] conv_info          Padding and stride information.
+     * @param[in] num_groups         (Optional) Number of groups. Default: 1.
+     * @param[in] weights_quant_info (Optional) Weights quantization information
+     * @param[in] out_quant_info     (Optional) Output quantization info
+     */
+    ConvolutionLayer(unsigned int           conv_width,
+                     unsigned int           conv_height,
+                     unsigned int           ofm,
+                     ITensorAccessorUPtr    weights,
+                     ITensorAccessorUPtr    bias,
+                     PadStrideInfo          conv_info,
+                     unsigned int           num_groups         = 1,
+                     const QuantizationInfo weights_quant_info = QuantizationInfo(),
+                     const QuantizationInfo out_quant_info     = QuantizationInfo())
+        : _conv_width(conv_width),
+          _conv_height(conv_height),
+          _ofm(ofm),
+          _conv_info(std::move(conv_info)),
+          _num_groups(num_groups),
+          _weights(std::move(weights)),
+          _bias(std::move(bias)),
+          _weights_quant_info(std::move(weights_quant_info)),
+          _out_quant_info(std::move(out_quant_info))
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        return GraphBuilder::add_convolution_node(s.graph(), common_params, input,
+                                                  Size2D(_conv_width, _conv_height), _ofm, _conv_info, _num_groups,
+                                                  s.hints().convolution_method_hint, s.hints().fast_math_hint,
+                                                  std::move(_weights), std::move(_bias), std::move(_weights_quant_info), std::move(_out_quant_info));
+    }
+
+private:
+    unsigned int           _conv_width;
+    unsigned int           _conv_height;
+    unsigned int           _ofm;
+    const PadStrideInfo    _conv_info;
+    unsigned int           _num_groups;
+    ITensorAccessorUPtr    _weights;
+    ITensorAccessorUPtr    _bias;
+    const QuantizationInfo _weights_quant_info;
+    const QuantizationInfo _out_quant_info;
+};
+
+/** Depthwise Convolution Layer */
+class DepthwiseConvolutionLayer final : public ILayer
+{
+public:
+    /** Construct a depthwise convolution layer.
+     *
+     * @param[in] conv_width  Convolution width.
+     * @param[in] conv_height Convolution height.
+     * @param[in] weights     Accessor to get kernel weights from.
+     * @param[in] bias        Accessor to get kernel bias from.
+     * @param[in] conv_info   Padding and stride information.
+     * @param[in] quant_info  (Optional) Quantization info used for weights
+     */
+    DepthwiseConvolutionLayer(unsigned int           conv_width,
+                              unsigned int           conv_height,
+                              ITensorAccessorUPtr    weights,
+                              ITensorAccessorUPtr    bias,
+                              PadStrideInfo          conv_info,
+                              const QuantizationInfo quant_info = QuantizationInfo())
+        : _conv_width(conv_width),
+          _conv_height(conv_height),
+          _conv_info(std::move(conv_info)),
+          _weights(std::move(weights)),
+          _bias(std::move(bias)),
+          _quant_info(std::move(quant_info))
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        return GraphBuilder::add_depthwise_convolution_node(s.graph(), common_params,
+                                                            input, Size2D(_conv_width, _conv_height), _conv_info,
+                                                            s.hints().depthwise_convolution_method_hint,
+                                                            std::move(_weights), std::move(_bias), std::move(_quant_info));
+    }
+
+private:
+    unsigned int           _conv_width;
+    unsigned int           _conv_height;
+    const PadStrideInfo    _conv_info;
+    ITensorAccessorUPtr    _weights;
+    ITensorAccessorUPtr    _bias;
+    const QuantizationInfo _quant_info;
+};
+
+/** Flatten Layer */
+class FlattenLayer final : public ILayer
+{
+public:
+    /** Construct a flatten layer. */
+    FlattenLayer()
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_flatten_node(s.graph(), common_params, input);
+    }
+};
+
+/** Fully Connected Layer */
+class FullyConnectedLayer final : public ILayer
+{
+public:
+    /** Construct a fully connected layer.
+     *
+     * @param[in] num_outputs Number of outputs.
+     * @param[in] weights     Accessor to get weights from.
+     * @param[in] bias        Accessor to get bias from.
+     */
+    FullyConnectedLayer(unsigned int        num_outputs,
+                        ITensorAccessorUPtr weights,
+                        ITensorAccessorUPtr bias)
+        : _num_outputs(num_outputs), _weights(std::move(weights)), _bias(std::move(bias))
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs,
+                                                       std::move(_weights), std::move(_bias));
+    }
+
+private:
+    unsigned int        _num_outputs;
+    ITensorAccessorUPtr _weights;
+    ITensorAccessorUPtr _bias;
+};
+
+/** Normalization Layer */
+class NormalizationLayer final : public ILayer
+{
+public:
+    /** Construct a normalization layer.
+     *
+     * @param[in] norm_info Normalization information.
+     */
+    NormalizationLayer(NormalizationLayerInfo norm_info)
+        : _norm_info(norm_info)
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_normalization_node(s.graph(), common_params, input, _norm_info);
+    }
+
+private:
+    NormalizationLayerInfo _norm_info;
+};
+
+/** Pooling Layer */
+class PoolingLayer final : public ILayer
+{
+public:
+    /** Construct a pooling layer.
+     *
+     * @param[in] pool_info Pooling information.
+     */
+    PoolingLayer(PoolingLayerInfo pool_info)
+        : _pool_info(pool_info)
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_pooling_node(s.graph(), common_params, input, _pool_info);
+    }
+
+private:
+    PoolingLayerInfo _pool_info;
+};
+
+/** Reshape Layer */
+class ReshapeLayer final : public ILayer
+{
+public:
+    /** Construct a reshape layer.
+     *
+     * @param[in] shape Target shape.
+     */
+    ReshapeLayer(TensorShape shape)
+        : _shape(shape)
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_reshape_node(s.graph(), common_params, input, _shape);
+    }
+
+private:
+    TensorShape _shape;
+};
+
+/** Scale Layer */
+class ScaleLayer final : public ILayer
+{
+public:
+    /** Construct a scale layer.
+     *
+     * @param[in] mul_w Accessor to get mul weight from.
+     * @param[in] add_w Accessor to get add weight from.
+     */
+    ScaleLayer(ITensorAccessorUPtr mul_w,
+               ITensorAccessorUPtr add_w)
+        : _mul_w(std::move(mul_w)), _add_w(std::move(add_w))
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_scale_layer(s.graph(), common_params, input, std::move(_mul_w), std::move(_add_w));
+    }
+
+private:
+    ITensorAccessorUPtr _mul_w;
+    ITensorAccessorUPtr _add_w;
+};
+
+/** Softmax Layer */
+class SoftmaxLayer final : public ILayer
+{
+public:
+    /** Construct a softmax layer.
+     *
+     * @param[in] beta (Optional) Beta value. Default 1.0.
+     */
+    SoftmaxLayer(float beta = 1.0f)
+        : _beta(beta)
+    {
+    }
+
+    NodeID create_layer(IStream &s) override
+    {
+        NodeParams  common_params = { name(), s.hints().target_hint };
+        NodeIdxPair input         = { s.tail_node(), 0 };
+        return GraphBuilder::add_softmax_node(s.graph(), common_params, input, _beta);
+    }
+
+private:
+    float _beta;
+};
+
+/** Branch Layer */
+class BranchLayer final : public ILayer
+{
+public:
+    /** Construct a branch layer
+     *
+     * @param[in] merge_method     Branch merging method
+     * @param[in] sub_stream1      First graph branch
+     * @param[in] sub_stream2      Second graph branch
+     * @param[in] rest_sub_streams Rest sub-graph branches
+     */
+    template <typename... Ts>
+    BranchLayer(BranchMergeMethod merge_method, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams)
+        : _branch_merge_method(merge_method), _sub_streams()
+    {
+        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1)));
+        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2)));
+
+        utility::for_each([&](SubStream && sub_stream)
+        {
+            _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
+        },
+        std::move(rest_sub_streams)...);
+    }
+    /** Construct a branch layer
+     *
+     * @param[in] sub_stream Sub-stream
+     */
+    template <typename... Ts>
+    BranchLayer(SubStream &&sub_stream)
+        : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_streams()
+    {
+        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
+    }
+    NodeID create_layer(IStream &s) override
+    {
+        NodeID     nid           = EmptyNodeID;
+        NodeParams common_params = { name(), s.hints().target_hint };
+        if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr)
+        {
+            nid = _sub_streams[0]->tail_node();
+        }
+        else if(_branch_merge_method == BranchMergeMethod::DEPTH_CONCATENATE)
+        {
+            // Collect tail nodes and perform DepthConcatenate
+            std::vector<NodeIdxPair> nodes;
+            for(auto &ss : _sub_streams)
+            {
+                if(ss && (ss->tail_node() != EmptyNodeID))
+                {
+                    const auto tail_node = s.graph().node(ss->tail_node());
+                    if(tail_node != nullptr && tail_node->type() != NodeType::Output)
+                    {
+                        nodes.push_back({ ss->tail_node(), 0 });
+                    }
+                }
+            }
+            nid = GraphBuilder::add_depth_concatenate_node(s.graph(), common_params, nodes);
+        }
+        else
+        {
+            ARM_COMPUTE_ERROR_ON(_sub_streams.size() != 2);
+            NodeIdxPair input0 = { _sub_streams[0]->tail_node(), 0 };
+            NodeIdxPair input1 = { _sub_streams[1]->tail_node(), 0 };
+            nid                = GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, EltwiseOperation::ADD);
+        }
+        return nid;
+    }
+
+private:
+    BranchMergeMethod                       _branch_merge_method;
+    std::vector<std::unique_ptr<SubStream>> _sub_streams;
+};
+} // namespace frontend
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_LAYERS_H__ */
diff --git a/arm_compute/graph/frontend/Stream.h b/arm_compute/graph/frontend/Stream.h
new file mode 100644
index 0000000..244d18e
--- /dev/null
+++ b/arm_compute/graph/frontend/Stream.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_STREAM_H__
+#define __ARM_COMPUTE_GRAPH_STREAM_H__
+
+#include "arm_compute/graph/frontend/IStream.h"
+#include "arm_compute/graph/frontend/IStreamOperators.h"
+#include "arm_compute/graph/frontend/Types.h"
+
+#include "arm_compute/graph/Graph.h"
+#include "arm_compute/graph/GraphContext.h"
+#include "arm_compute/graph/GraphManager.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace frontend
+{
+// Forward Declarations
+class ILayer;
+
+/** Stream frontend class to construct simple graphs in a stream fashion */
+class Stream final : public IStream
+{
+public:
+    /** Constructor
+     *
+     * @param[in] id   Stream id
+     * @param[in] name Stream name
+     */
+    Stream(size_t id, std::string name);
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    Stream(const Stream &) = delete;
+    /** Default move constructor */
+    Stream(Stream &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    Stream &operator=(const Stream &) = delete;
+    /** Default move assignment operator */
+    Stream &operator=(Stream &&) = default;
+    /** Finalizes the stream for an execution target
+     *
+     * @param[in] target Execution target
+     * @param[in] config (Optional) Graph configuration to use
+     */
+    void finalize(Target target, const GraphConfig &config);
+    /** Executes the stream **/
+    void run();
+
+    // Inherited overridden methods
+    void add_layer(ILayer &layer) override;
+    Graph       &graph() override;
+    const Graph &graph() const override;
+
+private:
+    GraphManager _manager; /**< Graph manager */
+    GraphContext _ctx;     /**< Graph context to use */
+    Graph        _g;       /**< Internal graph representation of the stream */
+};
+} // namespace frontend
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_STREAM_H__ */
\ No newline at end of file
diff --git a/arm_compute/graph/frontend/SubStream.h b/arm_compute/graph/frontend/SubStream.h
new file mode 100644
index 0000000..c084899
--- /dev/null
+++ b/arm_compute/graph/frontend/SubStream.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_SUB_STREAM_H__
+#define __ARM_COMPUTE_GRAPH_SUB_STREAM_H__
+
+#include "arm_compute/graph/frontend/IStream.h"
+#include "arm_compute/graph/frontend/IStreamOperators.h"
+#include "arm_compute/graph/frontend/Types.h"
+
+#include <memory>
+#include <vector>
+
+namespace arm_compute
+{
+namespace graph
+{
+// Forward declarations
+class Graph;
+
+namespace frontend
+{
+// Forward declarations
+class ILayer;
+
+/** Sub stream class*/
+class SubStream final : public IStream
+{
+public:
+    /** Default Constructor
+     *
+     * @param[in] s Parent stream
+     */
+    SubStream(IStream &s);
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    SubStream(const SubStream &) = delete;
+    /** Default move constructor */
+    SubStream(SubStream &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    SubStream &operator=(const SubStream &) = delete;
+    /** Default move assignment operator */
+    SubStream &operator=(SubStream &&) = default;
+
+    // Inherited overridden methods
+    void add_layer(ILayer &layer) override;
+    Graph       &graph() override;
+    const Graph &graph() const override;
+
+private:
+    IStream &_s; /**< Parent stream (assume that the lifetime of the parent is longer) */
+};
+} // namespace frontend
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_SUB_STREAM_H__ */
diff --git a/arm_compute/graph/frontend/Types.h b/arm_compute/graph/frontend/Types.h
new file mode 100644
index 0000000..4789361
--- /dev/null
+++ b/arm_compute/graph/frontend/Types.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_STREAM_TYPES_H__
+#define __ARM_COMPUTE_GRAPH_STREAM_TYPES_H__
+
+#include "arm_compute/graph/Types.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+namespace frontend
+{
+// Import types for graph
+using graph::DataType;
+using graph::DataLayout;
+using graph::TensorShape;
+
+using graph::ActivationLayerInfo;
+using graph::NormalizationLayerInfo;
+using graph::NormType;
+using graph::PadStrideInfo;
+using graph::PoolingLayerInfo;
+using graph::PoolingType;
+using graph::Target;
+using graph::ConvolutionMethod;
+using graph::FastMathHint;
+using graph::DepthwiseConvolutionMethod;
+using graph::TensorDescriptor;
+using graph::DimensionRoundingType;
+using graph::GraphConfig;
+
+/** Branch layer merging method */
+enum class BranchMergeMethod
+{
+    DEPTH_CONCATENATE, /**< Concatenate across depth */
+    ADD                /**< Adds the results of each stream */
+};
+
+/** Hints that can be passed to the stream to expose parameterization */
+struct StreamHints
+{
+    Target                     target_hint                       = { Target::UNSPECIFIED };                 /**< Target execution hint */
+    ConvolutionMethod          convolution_method_hint           = { ConvolutionMethod::DEFAULT };          /**< Convolution method hint */
+    DepthwiseConvolutionMethod depthwise_convolution_method_hint = { DepthwiseConvolutionMethod::DEFAULT }; /**< Depthwise Convolution method hint */
+    FastMathHint               fast_math_hint                    = { FastMathHint::DISABLED };              /**< Fast math hint */
+};
+} // namespace frontend
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_STREAM_TYPES_H__ */
\ No newline at end of file
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h
similarity index 64%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/mutators/DepthConcatSubTensorMutator.h
index b5d1bc5..0ddd3fa 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,26 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__
+#define __ARM_COMPUTE_GRAPH_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/IGraphMutator.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+/** Mutation pass to optimize depth concatenation operations by using sub-tensors
+ *
+ * @warning Always run as one of the last mutation pass as optimizations might change the parent of sub-tensors.
+ **/
+class DepthConcatSubTensorMutator final : public IGraphMutator
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited methods overridden
+    virtual void mutate(Graph &g) override;
+    const char *name() override;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ */
diff --git a/arm_compute/graph/nodes/FloorLayer.h b/arm_compute/graph/mutators/GraphMutators.h
similarity index 62%
copy from arm_compute/graph/nodes/FloorLayer.h
copy to arm_compute/graph/mutators/GraphMutators.h
index 146e2c1..a91bc91 100644
--- a/arm_compute/graph/nodes/FloorLayer.h
+++ b/arm_compute/graph/mutators/GraphMutators.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,25 +21,12 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_GRAPH_MUTATORS_H__
+#define __ARM_COMPUTE_GRAPH_GRAPH_MUTATORS_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-namespace arm_compute
-{
-namespace graph
-{
-/** Floor layer node */
-class FloorLayer final : public INode
-{
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
+#include "arm_compute/graph/mutators/DepthConcatSubTensorMutator.h"
+#include "arm_compute/graph/mutators/InPlaceOperationMutator.h"
+#include "arm_compute/graph/mutators/NodeFusionMutator.h"
+#include "arm_compute/graph/mutators/SplitLayerSubTensorMutator.h"
 
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_GRAPH_MUTATORS_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/mutators/InPlaceOperationMutator.h
similarity index 67%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/mutators/InPlaceOperationMutator.h
index b5d1bc5..69de2f1 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/mutators/InPlaceOperationMutator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,23 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_INPLACE_OPERATION_MUTATOR_H__
+#define __ARM_COMPUTE_GRAPH_INPLACE_OPERATION_MUTATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/IGraphMutator.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+/** Mutation pass to optimize operations that can be performed in-place */
+class InPlaceOperationMutator final : public IGraphMutator
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited methods overridden
+    virtual void mutate(Graph &g) override;
+    const char *name() override;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_INPLACE_OPERATION_MUTATOR_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/mutators/NodeFusionMutator.h
similarity index 65%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/mutators/NodeFusionMutator.h
index b5d1bc5..8f16c65 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/mutators/NodeFusionMutator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,32 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_NODE_FUSION_MUTATOR_H__
+#define __ARM_COMPUTE_GRAPH_NODE_FUSION_MUTATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/IGraphMutator.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+namespace detail
+{
+/** Fused batch normalization with activation
+ *
+ * @param[in] g Graph to perform operation fusion on
+ */
+void fuse_batch_norm_with_activation(Graph &g);
+} // namespace detail
+
+/** Mutation pass to fuss nodes */
+class NodeFusionMutator final : public IGraphMutator
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited methods overridden
+    virtual void mutate(Graph &g) override;
+    const char *name() override;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_NODE_FUSION_MUTATOR_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h
similarity index 66%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/mutators/SplitLayerSubTensorMutator.h
index b5d1bc5..f349bb9 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,26 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__
+#define __ARM_COMPUTE_GRAPH_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+#include "arm_compute/graph/IGraphMutator.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+/** Mutation pass to optimize split operations by using sub-tensors
+ *
+ * @warning This is compulsory to run in case Split layers are present in the model
+ **/
+class SplitLayerSubTensorMutator final : public IGraphMutator
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited methods overridden
+    virtual void mutate(Graph &g) override;
+    const char *name() override;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ */
diff --git a/arm_compute/graph/nodes/ActivationLayer.h b/arm_compute/graph/nodes/ActivationLayerNode.h
similarity index 62%
rename from arm_compute/graph/nodes/ActivationLayer.h
rename to arm_compute/graph/nodes/ActivationLayerNode.h
index bc619a8..570351b 100644
--- a/arm_compute/graph/nodes/ActivationLayer.h
+++ b/arm_compute/graph/nodes/ActivationLayerNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,34 +21,39 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
 
 namespace arm_compute
 {
 namespace graph
 {
 /** Activation Layer node */
-class ActivationLayer final : public INode
+class ActivationLayerNode final : public INode
 {
 public:
-    /** Default Constructor
+    /** Constructor
      *
-     * @param[in] activation_info Activation layer info
+     * @param[in] info Activation Layer information
      */
-    ActivationLayer(const ActivationLayerInfo activation_info);
+    ActivationLayerNode(ActivationLayerInfo info);
+    /** Activation metadata accessor
+     *
+     * @return The activation info of the layer
+     */
+    ActivationLayerInfo activation_info() const;
 
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
 
 private:
-    const ActivationLayerInfo _activation_info; /**< Activation layer info */
+    ActivationLayerInfo _info;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/BatchNormalizationLayer.h b/arm_compute/graph/nodes/BatchNormalizationLayer.h
deleted file mode 100644
index abbf09a..0000000
--- a/arm_compute/graph/nodes/BatchNormalizationLayer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_BATCHNORMALIZATION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_BATCHNORMALIZATION_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** BatchNormalization layer node */
-class BatchNormalizationLayer final : public INode
-{
-public:
-    /** Default constructor
-     *
-     * @param[in] mean     Mean values tensor
-     * @param[in] var      Var values tensor
-     * @param[in] gamma    Gamma values tensor
-     * @param[in] beta     Beta values tensor
-     * @param[in] epsilon  Epsilon value
-     * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Only RELU, BOUNDED_RELU and LU_BOUNDED_RELU supported.
-     */
-    template <typename AccessorType>
-    BatchNormalizationLayer(AccessorType &&mean, AccessorType &&var, AccessorType &&gamma, AccessorType &&beta, float epsilon, ActivationLayerInfo act_info = ActivationLayerInfo())
-        : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon), _act_info(act_info)
-    {
-        set_supports_in_place(true);
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    Tensor              _mean;
-    Tensor              _var;
-    Tensor              _gamma;
-    Tensor              _beta;
-    float               _epsilon;
-    ActivationLayerInfo _act_info;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_BATCHNORMALIZATION_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/BatchNormalizationLayerNode.h b/arm_compute/graph/nodes/BatchNormalizationLayerNode.h
new file mode 100644
index 0000000..a364d1c
--- /dev/null
+++ b/arm_compute/graph/nodes/BatchNormalizationLayerNode.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_BATCH_NORMALIZATION_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_BATCH_NORMALIZATION_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Batch Normalization Layer node */
+class BatchNormalizationLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] epsilon          (Optional) Epsilon parameter. Defaults to 1.f
+     * @param[in] fused_activation (Optional) Fused activation layer. Disabled if not specified
+     */
+    BatchNormalizationLayerNode(float epsilon = 1.f, ActivationLayerInfo fused_activation = ActivationLayerInfo());
+    /** Epsilon parameter accessor
+     *
+     * @return Epsilon parameter
+     */
+    float epsilon() const;
+    /** Returns fused activation
+     *
+     * @return Fused activation
+     */
+    ActivationLayerInfo fused_activation() const;
+    /** Sets fused activation
+     *
+     * @param[in] fused_activation Fused activation to set
+     */
+    void set_fused_activation(ActivationLayerInfo fused_activation);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    float               _epsilon;
+    ActivationLayerInfo _fused_activation;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_BATCH_NORMALIZATION_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/BranchLayer.h b/arm_compute/graph/nodes/BranchLayer.h
deleted file mode 100644
index ca1892f..0000000
--- a/arm_compute/graph/nodes/BranchLayer.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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_GRAPH_BRANCH_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_BRANCH_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/SubGraph.h"
-#include "arm_compute/graph/SubTensor.h"
-#include "arm_compute/graph/Types.h"
-
-#include "arm_compute/core/utils/misc/utility.h"
-
-#include <vector>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Branch Layer node */
-class BranchLayer final : public INode
-{
-public:
-    /** Default Constructor
-     *
-     * @param[in] merge_method    Branch merging method
-     * @param[in] sub_graph1      First graph branch
-     * @param[in] sub_graph2      Second graph branch
-     * @param[in] rest_sub_graphs Rest sub-graph branches
-     */
-    template <typename... Ts>
-    BranchLayer(BranchMergeMethod merge_method, SubGraph &&sub_graph1, SubGraph &&sub_graph2, Ts &&... rest_sub_graphs)
-        : _branch_merge_method(merge_method), _sub_graphs()
-    {
-        _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph1)));
-        _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph2)));
-
-        utility::for_each([&](SubGraph && sub_graph)
-        {
-            _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph)));
-        },
-        std::move(rest_sub_graphs)...);
-    }
-    /** Default Constructor
-     *
-     * @param[in] sub_graph Sub graph
-     */
-    template <typename... Ts>
-    BranchLayer(SubGraph &&sub_graph)
-        : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_graphs()
-    {
-        _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph)));
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    BranchMergeMethod                      _branch_merge_method;
-    std::vector<std::unique_ptr<SubGraph>> _sub_graphs;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_BRANCH_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/nodes/ConstNode.h
similarity index 66%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/nodes/ConstNode.h
index b5d1bc5..3216a3a 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/nodes/ConstNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,34 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_CONST_NODE_H__
+#define __ARM_COMPUTE_GRAPH_CONST_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+/** Const node */
+class ConstNode final : public INode
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Constructor
+     *
+     * @param[in] desc Tensor descriptor
+     */
+    ConstNode(TensorDescriptor desc);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    TensorDescriptor _desc;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_CONST_NODE_H__ */
diff --git a/arm_compute/graph/nodes/ConvolutionLayer.h b/arm_compute/graph/nodes/ConvolutionLayer.h
deleted file mode 100644
index 1806190..0000000
--- a/arm_compute/graph/nodes/ConvolutionLayer.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_CONVOLUTION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/SubTensor.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
-
-#include <memory>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Convolution layer node */
-class ConvolutionLayer final : public INode
-{
-public:
-    /** Default Constructor
-     *
-     * @param[in] conv_width         Convolution width
-     * @param[in] conv_height        Convolution height
-     * @param[in] ofm                Output feature map
-     * @param[in] weights            Weights of the convolution layer
-     * @param[in] biases             Bias of the convolution layer
-     * @param[in] conv_info          Convolution information
-     * @param[in] num_groups         (Optional) Number of groups, default = 1
-     * @param[in] weights_info       (Optional) Weights information
-     * @param[in] weights_quant_info (Optional) Weights quantization information
-     * @param[in] out_quant_info     (Optional) Output quantization info
-     */
-    template <typename AccessorTypeWeights, typename AccessorTypeBiases>
-    ConvolutionLayer(unsigned int           conv_width,
-                     unsigned int           conv_height,
-                     unsigned int           ofm,
-                     AccessorTypeWeights &&weights,
-                     AccessorTypeBiases   &&biases,
-                     const PadStrideInfo    conv_info,
-                     unsigned int           num_groups         = 1,
-                     const WeightsInfo      weights_info       = WeightsInfo(),
-                     const QuantizationInfo weights_quant_info = QuantizationInfo(),
-                     const QuantizationInfo out_quant_info     = QuantizationInfo())
-        : _conv_width(conv_width),
-          _conv_height(conv_height),
-          _ofm(ofm),
-          _weights(std::move(weights)),
-          _biases(std::move(biases)),
-          _conv_info(std::move(conv_info)),
-          _num_groups(num_groups),
-          _weights_info(std::move(weights_info)),
-          _weights_quant_info(std::move(weights_quant_info)),
-          _out_quant_info(std::move(out_quant_info)),
-          _is(nullptr),
-          _os(nullptr),
-          _ws(nullptr),
-          _bs(nullptr)
-    {
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    /** Instantiates a non-grouped convolution
-     *
-     * @param[in] input            Input tensor
-     * @param[in] output           Output tensor
-     * @param[in] conv_method_hint Hint that specifies which convolution layer method to use
-     *
-     * @return Convolution function
-     */
-    std::unique_ptr<arm_compute::IFunction> instantiate_convolution(ITensor *input, ITensor *output, ConvolutionMethodHint conv_method_hint);
-    /** Instantiates a grouped convolution
-     *
-     * @param[in] input            Input tensor
-     * @param[in] output           Output tensor
-     * @param[in] conv_method_hint Hint that specifies which convolution layer method to use
-     *
-     * @return Grouped Convolution function
-     */
-    std::unique_ptr<arm_compute::IFunction> instantiate_grouped_convolution(ITensor *input, ITensor *output, ConvolutionMethodHint conv_method_hint);
-
-private:
-    unsigned int           _conv_width;         /**< Convolution width */
-    unsigned int           _conv_height;        /**< Convolution height */
-    unsigned int           _ofm;                /**< Output feature maps */
-    Tensor                 _weights;            /**< Weights tensor */
-    Tensor                 _biases;             /**< Biases tensor */
-    const PadStrideInfo    _conv_info;          /**< Convolution layer information */
-    unsigned int           _num_groups;         /**< Number of groups */
-    const WeightsInfo      _weights_info;       /**< Convolution layer weights information */
-    const QuantizationInfo _weights_quant_info; /**< Output quantization information */
-    const QuantizationInfo _out_quant_info;     /**< Output quantization information */
-
-    std::unique_ptr<SubTensor[]> _is; /**< Input tensor sub-tensors used for grouped convolution */
-    std::unique_ptr<SubTensor[]> _os; /**< Output tensor sub-tensors used for grouped convolution */
-    std::unique_ptr<SubTensor[]> _ws; /**< Weights tensor sub-tensors used for grouped convolution */
-    std::unique_ptr<SubTensor[]> _bs; /**< Biases tensor sub-tensors used for grouped convolution */
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/ConvolutionLayerNode.h b/arm_compute/graph/nodes/ConvolutionLayerNode.h
new file mode 100644
index 0000000..aca6028
--- /dev/null
+++ b/arm_compute/graph/nodes/ConvolutionLayerNode.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_CONVOLUTION_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Convolution Layer node */
+class ConvolutionLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] info           Convolution layer attributes
+     * @param[in] method         (Optional) Convolution method to use
+     * @param[in] fast_math_hint (Optional) Fast math hint
+     * @param[in] out_quant_info (Optional) Output quantization info
+     */
+    ConvolutionLayerNode(PadStrideInfo info, ConvolutionMethod method = ConvolutionMethod::DEFAULT, FastMathHint fast_math_hint = FastMathHint::DISABLED,
+                         QuantizationInfo out_quant_info = QuantizationInfo());
+    /** Sets the convolution layer method to use
+     *
+     * @param[in] method Method to use for convolution
+     */
+    void set_convolution_method(ConvolutionMethod method);
+    /** Convolution layer method accessor
+     *
+     * @note This is an indication on which convolution layer implementation to use,
+     *       if it fails to be created the library's heuristic approach will be used
+     *
+     * @return Convolution layer method to be used by the node
+     */
+    ConvolutionMethod convolution_method() const;
+    /** Sets the fast math fast hint
+     *
+     * @param[in] hint Hint to use for convolution
+     */
+    void set_fast_math_hint(FastMathHint hint);
+    /** Fast math hint accessor
+     *
+     * @return Fast math hint to be used by the node
+     */
+    FastMathHint fast_math_hint() const;
+    /** Convolution metadata accessor
+     *
+     * @return Convolution information
+     */
+    PadStrideInfo convolution_info() const;
+    /** Computes convolution output descriptor
+     *
+     * @param[in] input_descriptor   Input descriptor
+     * @param[in] weights_descriptor Weights descriptor
+     * @param[in] info               Convolution operation attributes
+     *
+     * @return Output descriptor
+     */
+    static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor,
+                                                      const TensorDescriptor &weights_descriptor,
+                                                      const PadStrideInfo    &info);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    PadStrideInfo     _info;
+    ConvolutionMethod _method;
+    FastMathHint      _fast_math_hint;
+    QuantizationInfo  _out_quant_info;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/DepthConcatenateLayerNode.h b/arm_compute/graph/nodes/DepthConcatenateLayerNode.h
new file mode 100644
index 0000000..ffdec70
--- /dev/null
+++ b/arm_compute/graph/nodes/DepthConcatenateLayerNode.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_DEPTH_CONCATENATE_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_DEPTH_CONCATENATE_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Depth Concatenation Layer node */
+class DepthConcatenateLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] total_nodes Number of nodes that will get concatenated
+     */
+    DepthConcatenateLayerNode(unsigned int total_nodes);
+    /** Computes depth concatenations output descriptor
+     *
+     * @param[in] input_descriptors Input descriptors
+     *
+     * @return Expected output descriptor
+     */
+    static TensorDescriptor compute_output_descriptor(const std::vector<TensorDescriptor> &input_descriptors);
+    /** Disables or not the depth concatenate node
+     *
+     * @warning This is used when depth concatenate is performed with sub-tensors,
+     *          where this node is used as a placeholder.
+     *
+     * @param[in] is_enabled If true a backend function is created to perform the depth concatenation (involves copying),
+     *                       while if false, no function is created and we assume that subtensors are properly set to simulate
+     *                       a no copy operation.
+     */
+    void set_enabled(bool is_enabled);
+    /** Enabled parameter accessor
+     *
+     * @return True if a backend function is to be created else false
+     */
+    bool is_enabled() const;
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    unsigned int _total_nodes;
+    bool         _is_enabled;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_DEPTH_CONCATENATE_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/DepthConvertLayer.h b/arm_compute/graph/nodes/DepthConvertLayer.h
deleted file mode 100644
index 03bf9b7..0000000
--- a/arm_compute/graph/nodes/DepthConvertLayer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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_GRAPH_DEPTHCONVERT_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_DEPTHCONVERT_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** DepthConvertLayer layer node */
-class DepthConvertLayer final : public INode
-{
-public:
-    /** Default constructor
-     *
-     * @param[in] policy          Convertion policy
-     * @param[in] shift           Shift value
-     * @param[in] output_datatype Output datatype
-     */
-    DepthConvertLayer(const ConvertPolicy policy, uint32_t shift, DataType output_datatype);
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    const ConvertPolicy _policy;
-    uint32_t            _shift;
-    DataType            _output_datatype;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_DEPTHCONVERT_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/DepthwiseConvolutionLayer.h b/arm_compute/graph/nodes/DepthwiseConvolutionLayer.h
deleted file mode 100644
index 2d4bd1e..0000000
--- a/arm_compute/graph/nodes/DepthwiseConvolutionLayer.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/SubTensor.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-#include "arm_compute/runtime/IFunction.h"
-
-#include <memory>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Convolution layer node */
-class DepthwiseConvolutionLayer final : public INode
-{
-public:
-    /** Default constructor
-     *
-     * @param[in] conv_width  Convolution width
-     * @param[in] conv_height Convolution height
-     * @param[in] weights     Weights values tensor
-     * @param[in] biases      Biases values tensor
-     * @param[in] conv_info   Convolution info
-     * @param[in] opt3x3      (Optional) If true executes DepthwiseConvolutionLayer3x3
-     * @param[in] quant_info  (Optional) Quantization info used for weights
-     */
-    template <typename AccessorType>
-    DepthwiseConvolutionLayer(unsigned int conv_width, unsigned int conv_height, AccessorType &&weights, AccessorType &&biases, const PadStrideInfo conv_info, bool opt3x3 = true,
-                              const QuantizationInfo quant_info = QuantizationInfo())
-        : _conv_width(conv_width), _conv_height(conv_height), _weights(std::move(weights)), _biases(std::move(biases)), _conv_info(conv_info), _opt3x3(opt3x3), _quant_info(std::move(quant_info))
-    {
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    unsigned int           _conv_width;
-    unsigned int           _conv_height;
-    Tensor                 _weights;
-    Tensor                 _biases;
-    const PadStrideInfo    _conv_info;
-    bool                   _opt3x3;
-    const QuantizationInfo _quant_info;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h b/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h
new file mode 100644
index 0000000..df6f456
--- /dev/null
+++ b/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Depthwise Convolution Layer node */
+class DepthwiseConvolutionLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] info   Convolution layer attributes
+     * @param[in] method Depthwise convolution method to use
+     */
+    DepthwiseConvolutionLayerNode(PadStrideInfo info, DepthwiseConvolutionMethod method = DepthwiseConvolutionMethod::DEFAULT);
+    /** Sets the depthwise convolution method to use
+     *
+     * @param[in] method Depthwise convolution method to use
+     */
+    void set_depthwise_convolution_method(DepthwiseConvolutionMethod method);
+    /** Depthwise convolution layer method accessor
+     *
+     * @note This is an indication on which depthwise implementation to use,
+     *       if it fails to be created the generic approach will be used
+     *
+     * @return Depthwise convolution layer method do be used by the node
+     */
+    DepthwiseConvolutionMethod depthwise_convolution_method() const;
+    /** Convolution metadata accessor
+     *
+     * @return Convolution information
+     */
+    PadStrideInfo convolution_info() const;
+    /** Computes depthwise convolution output descriptor
+     *
+     * @param[in] input_descriptor   Input descriptor
+     * @param[in] weights_descriptor Weights descriptor
+     * @param[in] info               Convolution operation attributes
+     *
+     * @return Output descriptor
+     */
+    static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor,
+                                                      const TensorDescriptor &weights_descriptor,
+                                                      const PadStrideInfo    &info);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    PadStrideInfo              _info;
+    DepthwiseConvolutionMethod _method;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/DequantizationLayer.h b/arm_compute/graph/nodes/DequantizationLayer.h
deleted file mode 100644
index f9b7e8a..0000000
--- a/arm_compute/graph/nodes/DequantizationLayer.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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_GRAPH_DEQUANTIZATION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_DEQUANTIZATION_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** DequantizationLayer layer node */
-class DequantizationLayer final : public INode
-{
-public:
-    /** Default constructor
-     *
-     * @param[in] min_max Min max value tensor
-     */
-    template <typename AccessorType>
-    DequantizationLayer(AccessorType &&min_max)
-        : _min_max(std::move(min_max))
-    {
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    Tensor _min_max;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_DEQUANTIZATION_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/EltwiseLayerNode.h b/arm_compute/graph/nodes/EltwiseLayerNode.h
new file mode 100644
index 0000000..09cbc75
--- /dev/null
+++ b/arm_compute/graph/nodes/EltwiseLayerNode.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_ELTWISE_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Eltwise Layer node */
+class EltwiseLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] op       Element-wise operation to perform
+     * @param[in] c_policy (Optional) Convert policy used for the operation
+     * @param[in] r_policy (Optional) Rounding policy used for the operation
+     */
+    EltwiseLayerNode(EltwiseOperation op, ConvertPolicy c_policy = ConvertPolicy::SATURATE, RoundingPolicy r_policy = RoundingPolicy::TO_ZERO);
+    /** Eltwise operation accessor
+     *
+     * @return Eltwise operation that is to be performed by the node
+     */
+    EltwiseOperation eltwise_operation() const;
+
+    /** Convert policy accessor
+     *
+     * @return Convert policy that is used in the node
+     */
+    ConvertPolicy convert_policy() const;
+
+    /** Rounding policy accessor
+     *
+     * @return Convert policy that is used in the node
+     */
+    RoundingPolicy rounding_policy() const;
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    EltwiseOperation _op;
+    ConvertPolicy    _convert_policy;
+    RoundingPolicy   _rounding_policy;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/FlattenLayer.h b/arm_compute/graph/nodes/FlattenLayer.h
deleted file mode 100644
index c5f51a2..0000000
--- a/arm_compute/graph/nodes/FlattenLayer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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_GRAPH_FLATTEN_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Flatten layer node */
-class FlattenLayer final : public INode
-{
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/nodes/FlattenLayerNode.h
similarity index 68%
rename from arm_compute/graph/nodes/SoftmaxLayer.h
rename to arm_compute/graph/nodes/FlattenLayerNode.h
index b5d1bc5..18a96ab 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/nodes/FlattenLayerNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,28 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+/** Flatten Layer node */
+class FlattenLayerNode final : public INode
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Default Constructor */
+    FlattenLayerNode();
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/FullyConnectedLayer.h b/arm_compute/graph/nodes/FullyConnectedLayer.h
deleted file mode 100644
index 270676a..0000000
--- a/arm_compute/graph/nodes/FullyConnectedLayer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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_GRAPH_FULLY_CONNECTED_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Tensor.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Fully connected layer node */
-class FullyConnectedLayer final : public INode
-{
-public:
-    /** Default constructor
-     *
-     * @param[in] num_neurons Number of neurons
-     * @param[in] weights     Weights of the fully connected layer
-     * @param[in] biases      Biases of the fully connected layer
-     */
-    template <typename AccessorTypeWeights, typename AccessorTypeBiases>
-    FullyConnectedLayer(unsigned int num_neurons, AccessorTypeWeights &&weights, AccessorTypeBiases &&biases)
-        : _num_neurons(num_neurons), _weights(std::move(weights)), _biases(std::move(biases))
-    {
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-    // Inherited methods overriden:
-private:
-    unsigned int _num_neurons; /**< Number of neurons */
-    Tensor       _weights;     /**< Weights tensor */
-    Tensor       _biases;      /**< Biases tensor */
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/FullyConnectedLayerNode.h b/arm_compute/graph/nodes/FullyConnectedLayerNode.h
new file mode 100644
index 0000000..3d1b689
--- /dev/null
+++ b/arm_compute/graph/nodes/FullyConnectedLayerNode.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_FULLY_CONNECTED_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Fully Connected Layer node */
+class FullyConnectedLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] num_outputs Number of neurons in the layer
+     */
+    FullyConnectedLayerNode(unsigned int num_outputs);
+    /** Computes weights descriptor
+     *
+     * @warning Works for inputs with 1D batch space
+     *
+     * @param[in] input_descriptor Input descriptor
+     * @param[in] num_outputs      Number of output neurons
+     *
+     * @return Weights descriptor
+     */
+    static TensorDescriptor compute_weights_descriptor(const TensorDescriptor &input_descriptor, unsigned int num_outputs);
+    /** Computes fully connected layer output descriptor
+     *
+     * @warning Works for inputs with 1D batch space
+     *
+     * @param[in] input_descriptor Input descriptor
+     * @param[in] num_outputs      Number of output neurons
+     *
+     * @return Output descriptor
+     */
+    static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, unsigned int num_outputs);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    unsigned int _num_outputs;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/nodes/InputNode.h
similarity index 66%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/nodes/InputNode.h
index b5d1bc5..4297c8a 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/nodes/InputNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,34 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_INPUT_NODE_H__
+#define __ARM_COMPUTE_GRAPH_INPUT_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
+/** Input Layer node */
+class InputNode final : public INode
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    /** Constructor
+     *
+     * @param[in] desc Tensor descriptor
+     */
+    InputNode(TensorDescriptor desc);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    TensorDescriptor _desc;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_INPUT_NODE_H__ */
diff --git a/arm_compute/graph/nodes/L2NormalizeLayer.h b/arm_compute/graph/nodes/L2NormalizeLayer.h
deleted file mode 100644
index a423306..0000000
--- a/arm_compute/graph/nodes/L2NormalizeLayer.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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_GRAPH_L2NORMALIZE_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_L2NORMALIZE_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** L2NormalizeLayer layer node */
-class L2NormalizeLayer final : public INode
-{
-public:
-    /** Default Constructor
-     *
-     * @param[in] axis    Dimension along which to reduce.
-     * @param[in] epsilon Lower bound value for the normalization.
-     */
-    explicit L2NormalizeLayer(unsigned int axis, float epsilon);
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    unsigned int _axis;
-    float        _epsilon;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_L2NORMALIZE_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/Nodes.h b/arm_compute/graph/nodes/Nodes.h
new file mode 100644
index 0000000..c39546c
--- /dev/null
+++ b/arm_compute/graph/nodes/Nodes.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_NODES_H__
+#define __ARM_COMPUTE_GRAPH_NODES_H__
+
+#include "arm_compute/graph/nodes/ActivationLayerNode.h"
+#include "arm_compute/graph/nodes/BatchNormalizationLayerNode.h"
+#include "arm_compute/graph/nodes/ConstNode.h"
+#include "arm_compute/graph/nodes/ConvolutionLayerNode.h"
+#include "arm_compute/graph/nodes/DepthConcatenateLayerNode.h"
+#include "arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h"
+#include "arm_compute/graph/nodes/EltwiseLayerNode.h"
+#include "arm_compute/graph/nodes/FlattenLayerNode.h"
+#include "arm_compute/graph/nodes/FullyConnectedLayerNode.h"
+#include "arm_compute/graph/nodes/InputNode.h"
+#include "arm_compute/graph/nodes/NormalizationLayerNode.h"
+#include "arm_compute/graph/nodes/OutputNode.h"
+#include "arm_compute/graph/nodes/PoolingLayerNode.h"
+#include "arm_compute/graph/nodes/ReshapeLayerNode.h"
+#include "arm_compute/graph/nodes/SoftmaxLayerNode.h"
+#include "arm_compute/graph/nodes/SplitLayerNode.h"
+
+#endif /* __ARM_COMPUTE_GRAPH_NODES_H__ */
diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/nodes/NodesFwd.h
similarity index 66%
copy from arm_compute/graph/nodes/SoftmaxLayer.h
copy to arm_compute/graph/nodes/NodesFwd.h
index b5d1bc5..b90cb5c 100644
--- a/arm_compute/graph/nodes/SoftmaxLayer.h
+++ b/arm_compute/graph/nodes/NodesFwd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,24 +21,31 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_NODES_FWD_H__
+#define __ARM_COMPUTE_GRAPH_NODES_FWD_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
 namespace arm_compute
 {
 namespace graph
 {
-/** Softmax layer node */
-class SoftmaxLayer final : public INode
-{
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
+// Forward declarations
+class INode;
+class ActivationLayerNode;
+class BatchNormalizationLayerNode;
+class ConstNode;
+class ConvolutionLayerNode;
+class DepthConcatenateLayerNode;
+class DepthwiseConvolutionLayerNode;
+class EltwiseLayerNode;
+class FlattenLayerNode;
+class FullyConnectedLayerNode;
+class InputNode;
+class NormalizationLayerNode;
+class OutputNode;
+class PoolingLayerNode;
+class ReshapeLayerNode;
+class SoftmaxLayerNode;
+class SplitLayerNode;
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_NODES_FWD_H__ */
diff --git a/arm_compute/graph/nodes/NormalizationLayer.h b/arm_compute/graph/nodes/NormalizationLayer.h
deleted file mode 100644
index e1c4509..0000000
--- a/arm_compute/graph/nodes/NormalizationLayer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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_GRAPH_NORMALIZATION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Normalization layer node */
-class NormalizationLayer final : public INode
-{
-public:
-    /** Default Constructor
-     *
-     * @param[in] norm_info Normalization layer information
-     */
-    explicit NormalizationLayer(const NormalizationLayerInfo norm_info);
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    const NormalizationLayerInfo _norm_info; /**< Normalization layer information */
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/NormalizationLayerNode.h b/arm_compute/graph/nodes/NormalizationLayerNode.h
new file mode 100644
index 0000000..43040e1
--- /dev/null
+++ b/arm_compute/graph/nodes/NormalizationLayerNode.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_NORMALIZATION_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Normalization Layer node */
+class NormalizationLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] norm_info Normalization Layer information
+     */
+    NormalizationLayerNode(NormalizationLayerInfo norm_info);
+    /** Normalization info accessor
+     *
+     * @return Normalization layer info
+     */
+    NormalizationLayerInfo normalization_info() const;
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    NormalizationLayerInfo _info;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/FloorLayer.h b/arm_compute/graph/nodes/OutputNode.h
similarity index 70%
rename from arm_compute/graph/nodes/FloorLayer.h
rename to arm_compute/graph/nodes/OutputNode.h
index 146e2c1..03d41eb 100644
--- a/arm_compute/graph/nodes/FloorLayer.h
+++ b/arm_compute/graph/nodes/OutputNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,25 +21,28 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__
+#define __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
+
 namespace arm_compute
 {
 namespace graph
 {
-/** Floor layer node */
-class FloorLayer final : public INode
+/** Output Layer node */
+class OutputNode final : public INode
 {
 public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
+    /** Default Constructor */
+    OutputNode();
 
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+};
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__ */
diff --git a/arm_compute/graph/nodes/PoolingLayerNode.h b/arm_compute/graph/nodes/PoolingLayerNode.h
new file mode 100644
index 0000000..d037ea2
--- /dev/null
+++ b/arm_compute/graph/nodes/PoolingLayerNode.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_POOLING_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Pooling Layer node */
+class PoolingLayerNode final : public INode
+{
+public:
+    /** Constructor
+     *
+     * @param[in] pool_info Pooling Layer information
+     */
+    PoolingLayerNode(PoolingLayerInfo pool_info);
+    /** Pooling metadata accessor
+     *
+     * @return Pooling Layer info
+     */
+    PoolingLayerInfo pooling_info() const;
+    /** Computes pooling output descriptor
+     *
+     * @param[in] input_descriptor Input descriptor
+     * @param[in] info             Pooling operation attributes
+     *
+     * @return Output descriptor
+     */
+    static TensorDescriptor compute_output_descriptor(const TensorDescriptor &input_descriptor, PoolingLayerInfo info);
+
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    PoolingLayerInfo _info;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/QuantizationLayer.h b/arm_compute/graph/nodes/QuantizationLayer.h
deleted file mode 100644
index a3ef025..0000000
--- a/arm_compute/graph/nodes/QuantizationLayer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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_GRAPH_QUANTIZATION_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_QUANTIZATION_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Quantization layer node */
-class QuantizationLayer final : public INode
-{
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_QUANTIZATION_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/ReshapeLayer.h b/arm_compute/graph/nodes/ReshapeLayerNode.h
similarity index 66%
rename from arm_compute/graph/nodes/ReshapeLayer.h
rename to arm_compute/graph/nodes/ReshapeLayerNode.h
index b727d33..5161af8 100644
--- a/arm_compute/graph/nodes/ReshapeLayer.h
+++ b/arm_compute/graph/nodes/ReshapeLayerNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,34 +21,34 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
 
 namespace arm_compute
 {
 namespace graph
 {
-/** Reshape layer node */
-class ReshapeLayer final : public INode
+/** Reshape Layer node */
+class ReshapeLayerNode final : public INode
 {
 public:
-    /** Default constructor
+    /** Constructor
      *
-     * @param[in] shape Output shape
+     * @param[in] shape Reshaped tensor shape
      */
-    ReshapeLayer(const TensorShape shape);
+    ReshapeLayerNode(TensorShape shape);
 
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
 
 private:
     TensorShape _shape;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/ResidualLayer.h b/arm_compute/graph/nodes/ResidualLayer.h
deleted file mode 100644
index 1eecf6f..0000000
--- a/arm_compute/graph/nodes/ResidualLayer.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2017-2018 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_GRAPH_RESIDUAL_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_RESIDUAL_LAYER_H__
-
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/SubGraph.h"
-#include "arm_compute/graph/Types.h"
-
-#include "arm_compute/core/utils/misc/utility.h"
-
-#include <vector>
-
-namespace arm_compute
-{
-namespace graph
-{
-/** Branch Layer node */
-class ResidualLayer final : public INode
-{
-public:
-    /** Default Constructor
-     *
-     * @param[in] sub_graph1 First graph branch
-     * @param[in] sub_graph2 Second graph branch
-     */
-    template <typename... Ts>
-    ResidualLayer(SubGraph &&sub_graph1, SubGraph &&sub_graph2)
-        : _sub_graphs()
-    {
-        _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph1)));
-        _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph2)));
-    }
-    /** Default Constructor
-     *
-     * @param[in] sub_graph Sub graph
-     */
-    template <typename... Ts>
-    ResidualLayer(SubGraph &&sub_graph)
-        : _sub_graphs()
-    {
-        _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph)));
-    }
-
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-
-private:
-    std::vector<std::unique_ptr<SubGraph>> _sub_graphs;
-};
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_RESIDUAL_LAYER_H__ */
diff --git a/arm_compute/graph/nodes/PoolingLayer.h b/arm_compute/graph/nodes/SoftmaxLayerNode.h
similarity index 63%
rename from arm_compute/graph/nodes/PoolingLayer.h
rename to arm_compute/graph/nodes/SoftmaxLayerNode.h
index 5c45bc0..6ace58d 100644
--- a/arm_compute/graph/nodes/PoolingLayer.h
+++ b/arm_compute/graph/nodes/SoftmaxLayerNode.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,34 +21,39 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__
 
-#include "arm_compute/graph/GraphContext.h"
 #include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
 
 namespace arm_compute
 {
 namespace graph
 {
-/** Pooling layer node */
-class PoolingLayer final : public INode
+/** Softmax Layer node */
+class SoftmaxLayerNode final : public INode
 {
 public:
-    /** Default Constructor
+    /** Constructor
      *
-     * @param pool_info Pooling layer information
+     * @param[in] beta (Optional) Beta parameter. Defaults to 1
      */
-    PoolingLayer(const PoolingLayerInfo pool_info);
+    SoftmaxLayerNode(float beta = 1.f);
+    /** Beta parameter accessor
+     *
+     * @return Beta parameter
+     */
+    float beta() const;
 
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
+    // Inherited overridden methods:
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
 
 private:
-    const PoolingLayerInfo _pool_info; /**< Pooling layer information */
+    float _beta;
 };
 } // namespace graph
 } // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/nodes/SplitLayerNode.h b/arm_compute/graph/nodes/SplitLayerNode.h
new file mode 100644
index 0000000..abd28ae
--- /dev/null
+++ b/arm_compute/graph/nodes/SplitLayerNode.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_SPLIT_LAYER_NODE_H__
+#define __ARM_COMPUTE_GRAPH_SPLIT_LAYER_NODE_H__
+
+#include "arm_compute/graph/INode.h"
+
+#include <tuple>
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Split Layer node */
+class SplitLayerNode final : public INode
+{
+public:
+    /** Default Constructor
+     *
+     * @param[in] num_splits Number of splits
+     * @param[in] axis       (Optional) Axis to split on. Supported axis >= 2. Defaults to 0
+     */
+    SplitLayerNode(unsigned int num_splits, unsigned int axis = 0);
+    /** Computes split layer output descriptor
+     *
+     * @param[in] input_descriptor Descriptor of the input tensor
+     * @param[in] num_splits       Number of splits
+     * @param[in] axis             Axis to perform the split on
+     * @param[in] idx              Index of the split
+     *
+     * @return  A pair with the descriptor of the split and the starting coordinates
+     */
+    static std::pair<TensorDescriptor, Coordinates> compute_output_descriptor(const TensorDescriptor &input_descriptor,
+                                                                              unsigned int num_splits, unsigned int axis, unsigned int idx);
+    /** Number of splits accessor
+     *
+     * @return Number of splits
+     */
+    unsigned int num_splits() const;
+    /** Split axis accessor
+     *
+     * @return Split axis
+     */
+    unsigned int axis() const;
+
+    // Inherited overridden methods:
+    Status           validate() const override;
+    NodeType         type() const override;
+    bool             forward_descriptors() override;
+    TensorDescriptor configure_output(size_t idx) const override;
+    void accept(INodeVisitor &v) override;
+
+private:
+    unsigned int _num_splits;
+    unsigned int _axis;
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_SPLIT_LAYER_NODE_H__ */
diff --git a/arm_compute/graph/printers/DotGraphPrinter.h b/arm_compute/graph/printers/DotGraphPrinter.h
new file mode 100644
index 0000000..1d355a5
--- /dev/null
+++ b/arm_compute/graph/printers/DotGraphPrinter.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018 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_GRAPH_DOTGRAPHPRINTER_H__
+#define __ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H__
+
+#include "arm_compute/graph/IGraphPrinter.h"
+
+#include "arm_compute/graph/INodeVisitor.h"
+
+#include <string>
+
+namespace arm_compute
+{
+namespace graph
+{
+/** Graph printer visitor. */
+class DotGraphVisitor final : public DefaultNodeVisitor
+{
+public:
+    /** Default Constructor **/
+    DotGraphVisitor() = default;
+    /** Returns the output information of the last visited node
+     *
+     * @return Information of the last visited node
+     */
+    const std::string &info() const;
+
+    // Reveal parent method
+    using DefaultNodeVisitor::visit;
+
+    // Inherited methods overridden
+    void visit(ActivationLayerNode &n) override;
+    void visit(BatchNormalizationLayerNode &n) override;
+    void visit(ConvolutionLayerNode &n) override;
+    void visit(DepthConcatenateLayerNode &n) override;
+    void visit(DepthwiseConvolutionLayerNode &n) override;
+    void visit(EltwiseLayerNode &n) override;
+    void visit(NormalizationLayerNode &n) override;
+    void visit(PoolingLayerNode &n) override;
+    void default_visit() override;
+
+private:
+    std::string _info{};
+};
+
+/** Graph printer interface */
+class DotGraphPrinter final : public IGraphPrinter
+{
+public:
+    // Inherited methods overridden
+    void print(const Graph &g, std::ostream &os) override;
+
+private:
+    /** Print dot graph header
+     *
+     * @param[in]  g  Graph
+     * @param[out] os Output stream to use
+     */
+    void print_header(const Graph &g, std::ostream &os);
+    /** Print dot graph footer
+     *
+     * @param[in]  g  Graph
+     * @param[out] os Output stream to use
+     */
+    void print_footer(const Graph &g, std::ostream &os);
+    /** Prints nodes in dot format
+     *
+     * @param[in]  g  Graph
+     * @param[out] os Output stream to use
+     */
+    void print_nodes(const Graph &g, std::ostream &os);
+    /** Prints edges in dot format
+     *
+     * @param[in]  g  Graph
+     * @param[out] os Output stream to use
+     */
+    void print_edges(const Graph &g, std::ostream &os);
+
+private:
+    DotGraphVisitor _dot_node_visitor = {};
+};
+} // namespace graph
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H__ */
diff --git a/arm_compute/graph/nodes/FloorLayer.h b/arm_compute/graph/printers/Printers.h
similarity index 62%
copy from arm_compute/graph/nodes/FloorLayer.h
copy to arm_compute/graph/printers/Printers.h
index 146e2c1..935e2bb 100644
--- a/arm_compute/graph/nodes/FloorLayer.h
+++ b/arm_compute/graph/printers/Printers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -21,25 +21,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
-#define __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__
+#ifndef __ARM_COMPUTE_GRAPH_PRINTERS_H__
+#define __ARM_COMPUTE_GRAPH_PRINTERS_H__
 
-#include "arm_compute/graph/GraphContext.h"
-#include "arm_compute/graph/INode.h"
-#include "arm_compute/graph/ITensorObject.h"
-#include "arm_compute/graph/Types.h"
-namespace arm_compute
-{
-namespace graph
-{
-/** Floor layer node */
-class FloorLayer final : public INode
-{
-public:
-    // Inherited methods overriden:
-    std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override;
-};
+#include "arm_compute/graph/printers/DotGraphPrinter.h"
 
-} // namespace graph
-} // namespace arm_compute
-#endif /* __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ */
+#endif /* __ARM_COMPUTE_GRAPH_PRINTERS_H__ */